ucx/map.c

changeset 31
287484519844
parent 22
112b85020dc9
equal deleted inserted replaced
30:d33eaaec15da 31:287484519844
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
143 static void* cx_map_simple_clone_func(void *dst, const void *src, const CxAllocator *al, void *data) { 147 static void* cx_map_shallow_clone_func(void *dst, const void *src, const CxAllocator *al, void *data) {
144 size_t elem_size = *(size_t*)data; 148 size_t elem_size = *(size_t*)data;
145 if (dst == NULL) dst = cxMalloc(al, elem_size); 149 if (dst == NULL) dst = cxMalloc(al, elem_size);
146 if (dst != NULL) memcpy(dst, src, elem_size); 150 if (dst != NULL) memcpy(dst, src, elem_size);
147 return dst; 151 return dst;
148 } 152 }
149 153
150 #define use_simple_clone_func(map) cx_map_simple_clone_func, NULL, (void*)&((map)->collection.elem_size) 154 #define use_shallow_clone_func(map) cx_map_shallow_clone_func, NULL, (void*)&((map)->collection.elem_size)
151 155
152 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,
153 const CxAllocator *clone_allocator, void *data) { 157 const CxAllocator *clone_allocator, void *data) {
154 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator; 158 if (clone_allocator == NULL) clone_allocator = cxDefaultAllocator;
155 CxMapIterator src_iter = cxMapIterator(src); 159 CxMapIterator src_iter = cxMapIterator(src);
301 } 305 }
302 } 306 }
303 return 0; 307 return 0;
304 } 308 }
305 309
306 int cxMapCloneSimple(CxMap *dst, const CxMap *src) { 310 int cxMapCloneShallow(CxMap *dst, const CxMap *src) {
307 return cxMapClone(dst, src, use_simple_clone_func(src)); 311 return cxMapClone(dst, src, use_shallow_clone_func(src));
308 } 312 }
309 313
310 int cxMapDifferenceSimple(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend) { 314 int cxMapDifferenceShallow(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend) {
311 return cxMapDifference(dst, minuend, subtrahend, use_simple_clone_func(minuend)); 315 return cxMapDifference(dst, minuend, subtrahend, use_shallow_clone_func(minuend));
312 } 316 }
313 317
314 int cxMapListDifferenceSimple(CxMap *dst, const CxMap *src, const CxList *keys) { 318 int cxMapListDifferenceShallow(CxMap *dst, const CxMap *src, const CxList *keys) {
315 return cxMapListDifference(dst, src, keys, use_simple_clone_func(src)); 319 return cxMapListDifference(dst, src, keys, use_shallow_clone_func(src));
316 } 320 }
317 321
318 int cxMapIntersectionSimple(CxMap *dst, const CxMap *src, const CxMap *other) { 322 int cxMapIntersectionShallow(CxMap *dst, const CxMap *src, const CxMap *other) {
319 return cxMapIntersection(dst, src, other, use_simple_clone_func(src)); 323 return cxMapIntersection(dst, src, other, use_shallow_clone_func(src));
320 } 324 }
321 325
322 int cxMapListIntersectionSimple(CxMap *dst, const CxMap *src, const CxList *keys) { 326 int cxMapListIntersectionShallow(CxMap *dst, const CxMap *src, const CxList *keys) {
323 return cxMapListIntersection(dst, src, keys, use_simple_clone_func(src)); 327 return cxMapListIntersection(dst, src, keys, use_shallow_clone_func(src));
324 } 328 }
325 329
326 int cxMapUnionSimple(CxMap *dst, const CxMap *src) { 330 int cxMapUnionShallow(CxMap *dst, const CxMap *src) {
327 return cxMapUnion(dst, src, use_simple_clone_func(src)); 331 return cxMapUnion(dst, src, use_shallow_clone_func(src));
328 } 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