| 287 The function `cxMapFree()` invokes the [destructor functions](collection.h.md#destructor-functions) for all elements, |
287 The function `cxMapFree()` invokes the [destructor functions](collection.h.md#destructor-functions) for all elements, |
| 288 and then deallocates the entire memory for the map. |
288 and then deallocates the entire memory for the map. |
| 289 |
289 |
| 290 ## Implement own Map Structures |
290 ## Implement own Map Structures |
| 291 |
291 |
| |
292 If the UCX [hash map](hash_map.h.md) implementation does not suit your needs, |
| |
293 you can also implement your own map. |
| |
294 To be compatible with the `CxMap` interface, it needs to store key/value pairs of the following form. |
| |
295 |
| 292 ```C |
296 ```C |
| 293 typedef struct { |
297 typedef struct { |
| 294 const CxHashKey *key; |
298 const CxHashKey *key; |
| 295 void *value; |
299 void *value; |
| 296 } CxMapEntry; |
300 } CxMapEntry; |
| 297 ``` |
301 ``` |
| 298 |
302 |
| 299 <warning> |
303 When you are declaring your map structure, a `CxMap` member must be embedded as first member of this structure. |
| 300 TODO: example |
304 Secondly, you need to implement the `cx_map_class` and assign it when allocating your map. |
| 301 </warning> |
305 |
| |
306 ```C |
| |
307 #include <cx/map.h> |
| |
308 |
| |
309 typedef struct { |
| |
310 CxMap base; |
| |
311 // ... data members for storing CxMapEntry elements go here ... |
| |
312 } MyMap; |
| |
313 |
| |
314 // declare the class - implement the functions somewhere |
| |
315 static cx_map_class my_map_class = { |
| |
316 my_map_destructor, |
| |
317 my_map_clear, |
| |
318 my_map_put, |
| |
319 my_map_get, |
| |
320 my_map_remove, |
| |
321 my_map_iterator, |
| |
322 }; |
| |
323 |
| |
324 // this function will create the map |
| |
325 CxMap *myMapCreate(const CxAllocator *allocator, size_t itemsize) { |
| |
326 if (allocator == NULL) { |
| |
327 allocator = cxDefaultAllocator; |
| |
328 } |
| |
329 |
| |
330 // allocate memory |
| |
331 MyMap *map = cxCalloc(allocator, 1, sizeof(MyMap)); |
| |
332 if (map == NULL) return NULL; |
| |
333 |
| |
334 // initialize base members |
| |
335 map->base.cl = &my_map_class; // <--- assign class here |
| |
336 map->base.collection.allocator = allocator; |
| |
337 if (itemsize == CX_STORE_POINTERS) { |
| |
338 map->base.collection.elem_size = sizeof(void *); |
| |
339 map->base.collection.store_pointer = true; |
| |
340 } else { |
| |
341 map->base.collection.elem_size = itemsize; |
| |
342 } |
| |
343 |
| |
344 // ... initialization of data members go here ... |
| |
345 |
| |
346 return (CxMap *) map; |
| |
347 } |
| |
348 ``` |
| 302 |
349 |
| 303 The required behavior for the implementations is described in the following table. |
350 The required behavior for the implementations is described in the following table. |
| 304 You can always look at the source code of the UCX hash map to get inspiration. |
351 You can always look at the source code of the UCX hash map to get inspiration. |
| 305 |
352 |
| 306 | Function | Description | |
353 | Function | Description | |