ucx/cx/map.h

changeset 888
af685cc9d623
parent 854
1c8401ece69e
equal deleted inserted replaced
877:b60487c3ec36 888:af685cc9d623
39 #include "common.h" 39 #include "common.h"
40 #include "collection.h" 40 #include "collection.h"
41 #include "string.h" 41 #include "string.h"
42 #include "hash_key.h" 42 #include "hash_key.h"
43 43
44 #ifndef UCX_LIST_H
45 // forward-declare CxList
46 typedef struct cx_list_s CxList;
47 #endif
48
44 #ifdef __cplusplus 49 #ifdef __cplusplus
45 extern "C" { 50 extern "C" {
46 #endif 51 #endif
47 52
48 /** Type for the UCX map. */ 53 /** Type for the UCX map. */
109 CX_ITERATOR_BASE; 114 CX_ITERATOR_BASE;
110 115
111 /** 116 /**
112 * Handle for the source map. 117 * Handle for the source map.
113 */ 118 */
114 union { 119 CxMap *map;
115 /**
116 * Access for mutating iterators.
117 */
118 CxMap *m;
119 /**
120 * Access for normal iterators.
121 */
122 const CxMap *c;
123 } map;
124 120
125 /** 121 /**
126 * Handle for the current element. 122 * Handle for the current element.
127 * 123 *
128 * @attention Depends on the map implementation, do not assume a type (better: do not use!). 124 * @attention Depends on the map implementation, do not assume a type (better: do not use!).
183 */ 179 */
184 void (*clear)(struct cx_map_s *map); 180 void (*clear)(struct cx_map_s *map);
185 181
186 /** 182 /**
187 * Add or overwrite an element. 183 * Add or overwrite an element.
188 */ 184 * If the @p value is @c NULL, the implementation
189 int (*put)( 185 * shall only allocate memory instead of adding an existing value to the map.
190 CxMap *map, 186 * Returns a pointer to the allocated memory or @c NULL if allocation fails.
191 CxHashKey key, 187 */
192 void *value 188 void *(*put)(CxMap *map, CxHashKey key, void *value);
193 );
194 189
195 /** 190 /**
196 * Returns an element. 191 * Returns an element.
197 */ 192 */
198 void *(*get)( 193 void *(*get)(const CxMap *map, CxHashKey key);
199 const CxMap *map,
200 CxHashKey key
201 );
202 194
203 /** 195 /**
204 * Removes an element. 196 * Removes an element.
205 * 197 *
206 * Implementations SHALL check if @p targetbuf is set and copy the elements 198 * Implementations SHALL check if @p targetbuf is set and copy the elements
208 * When @p targetbuf is not set, the destructors SHALL be invoked. 200 * When @p targetbuf is not set, the destructors SHALL be invoked.
209 * 201 *
210 * The function SHALL return zero when the @p key was found and 202 * The function SHALL return zero when the @p key was found and
211 * non-zero, otherwise. 203 * non-zero, otherwise.
212 */ 204 */
213 int (*remove)( 205 int (*remove)(CxMap *map, CxHashKey key, void *targetbuf);
214 CxMap *map,
215 CxHashKey key,
216 void *targetbuf
217 );
218 206
219 /** 207 /**
220 * Creates an iterator for this map. 208 * Creates an iterator for this map.
221 */ 209 */
222 CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); 210 CxMapIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
225 /** 213 /**
226 * A shared instance of an empty map. 214 * A shared instance of an empty map.
227 * 215 *
228 * Writing to that map is not allowed. 216 * Writing to that map is not allowed.
229 * 217 *
230 * You can use this is a placeholder for initializing CxMap pointers 218 * You can use this as a placeholder for initializing CxMap pointers
231 * for which you do not want to reserve memory right from the beginning. 219 * for which you do not want to reserve memory right from the beginning.
232 */ 220 */
233 cx_attr_export 221 CX_EXPORT extern CxMap *const cxEmptyMap;
234 extern CxMap *const cxEmptyMap;
235 222
236 /** 223 /**
237 * Deallocates the memory of the specified map. 224 * Deallocates the memory of the specified map.
238 * 225 *
239 * Also calls the content destructor functions for each element, if specified. 226 * Also calls the content destructor functions for each element, if specified.
240 * 227 *
241 * @param map the map to be freed 228 * @param map the map to be freed
242 */ 229 */
243 cx_attr_export 230 CX_EXPORT void cxMapFree(CxMap *map);
244 void cxMapFree(CxMap *map);
245 231
246 232
247 /** 233 /**
248 * Clears a map by removing all elements. 234 * Clears a map by removing all elements.
249 * 235 *
250 * Also calls the content destructor functions for each element, if specified. 236 * Also calls the content destructor functions for each element, if specified.
251 * 237 *
252 * @param map the map to be cleared 238 * @param map the map to be cleared
253 */ 239 */
254 cx_attr_nonnull 240 cx_attr_nonnull
255 static inline void cxMapClear(CxMap *map) { 241 CX_EXPORT void cxMapClear(CxMap *map);
256 map->cl->clear(map);
257 }
258 242
259 /** 243 /**
260 * Returns the number of elements in this map. 244 * Returns the number of elements in this map.
261 * 245 *
262 * @param map the map 246 * @param map the map
263 * @return the number of stored elements 247 * @return the number of stored elements
264 */ 248 */
265 cx_attr_nonnull 249 cx_attr_nonnull
266 static inline size_t cxMapSize(const CxMap *map) { 250 CX_EXPORT size_t cxMapSize(const CxMap *map);
267 return map->collection.size;
268 }
269 251
270 /** 252 /**
271 * Creates a value iterator for a map. 253 * Creates a value iterator for a map.
272 * 254 *
273 * When the map is storing pointers, those pointers are returned. 255 * When the map is storing pointers, those pointers are returned.
275 * respective elements are stored. 257 * respective elements are stored.
276 * 258 *
277 * @note An iterator iterates over all elements successively. Therefore, the order 259 * @note An iterator iterates over all elements successively. Therefore, the order
278 * highly depends on the map implementation and may change arbitrarily when the contents change. 260 * highly depends on the map implementation and may change arbitrarily when the contents change.
279 * 261 *
280 * @param map the map to create the iterator for 262 * @param map the map to create the iterator for (can be @c NULL)
281 * @return an iterator for the currently stored values 263 * @return an iterator for the currently stored values
282 */ 264 */
283 cx_attr_nonnull
284 cx_attr_nodiscard 265 cx_attr_nodiscard
285 static inline CxMapIterator cxMapIteratorValues(const CxMap *map) { 266 CX_EXPORT CxMapIterator cxMapIteratorValues(const CxMap *map);
286 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
287 }
288 267
289 /** 268 /**
290 * Creates a key iterator for a map. 269 * Creates a key iterator for a map.
291 * 270 *
292 * The elements of the iterator are keys of type CxHashKey and the pointer returned 271 * The elements of the iterator are keys of type CxHashKey, and the pointer returned
293 * during iterator shall be treated as @c const @c CxHashKey* . 272 * during iterator shall be treated as @c const @c CxHashKey* .
294 * 273 *
295 * @note An iterator iterates over all elements successively. Therefore, the order 274 * @note An iterator iterates over all elements successively. Therefore, the order
296 * highly depends on the map implementation and may change arbitrarily when the contents change. 275 * highly depends on the map implementation and may change arbitrarily when the contents change.
297 * 276 *
298 * @param map the map to create the iterator for 277 * @param map the map to create the iterator for (can be @c NULL)
299 * @return an iterator for the currently stored keys 278 * @return an iterator for the currently stored keys
300 */ 279 */
301 cx_attr_nonnull
302 cx_attr_nodiscard 280 cx_attr_nodiscard
303 static inline CxMapIterator cxMapIteratorKeys(const CxMap *map) { 281 CX_EXPORT CxMapIterator cxMapIteratorKeys(const CxMap *map);
304 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
305 }
306 282
307 /** 283 /**
308 * Creates an iterator for a map. 284 * Creates an iterator for a map.
309 * 285 *
310 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned 286 * The elements of the iterator are key/value pairs of type CxMapEntry, and the pointer returned
311 * during iterator shall be treated as @c const @c CxMapEntry* . 287 * during iterator shall be treated as @c const @c CxMapEntry* .
312 * 288 *
313 * @note An iterator iterates over all elements successively. Therefore, the order 289 * @note An iterator iterates over all elements successively. Therefore, the order
314 * highly depends on the map implementation and may change arbitrarily when the contents change. 290 * highly depends on the map implementation and may change arbitrarily when the contents change.
315 * 291 *
316 * @param map the map to create the iterator for 292 * @param map the map to create the iterator for (can be @c NULL)
317 * @return an iterator for the currently stored entries 293 * @return an iterator for the currently stored entries
318 * @see cxMapIteratorKeys() 294 * @see cxMapIteratorKeys()
319 * @see cxMapIteratorValues() 295 * @see cxMapIteratorValues()
320 */ 296 */
321 cx_attr_nonnull
322 cx_attr_nodiscard 297 cx_attr_nodiscard
323 static inline CxMapIterator cxMapIterator(const CxMap *map) { 298 CX_EXPORT CxMapIterator cxMapIterator(const CxMap *map);
324 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
325 }
326
327
328 /**
329 * Creates a mutating iterator over the values of a map.
330 *
331 * When the map is storing pointers, those pointers are returned.
332 * Otherwise, the iterator iterates over pointers to the memory within the map where the
333 * respective elements are stored.
334 *
335 * @note An iterator iterates over all elements successively. Therefore, the order
336 * highly depends on the map implementation and may change arbitrarily when the contents change.
337 *
338 * @param map the map to create the iterator for
339 * @return an iterator for the currently stored values
340 */
341 cx_attr_nonnull
342 cx_attr_nodiscard
343 cx_attr_export
344 CxMapIterator cxMapMutIteratorValues(CxMap *map);
345
346 /**
347 * Creates a mutating iterator over the keys of a map.
348 *
349 * The elements of the iterator are keys of type CxHashKey and the pointer returned
350 * during iterator shall be treated as @c const @c CxHashKey* .
351 *
352 * @note An iterator iterates over all elements successively. Therefore, the order
353 * highly depends on the map implementation and may change arbitrarily when the contents change.
354 *
355 * @param map the map to create the iterator for
356 * @return an iterator for the currently stored keys
357 */
358 cx_attr_nonnull
359 cx_attr_nodiscard
360 cx_attr_export
361 CxMapIterator cxMapMutIteratorKeys(CxMap *map);
362
363 /**
364 * Creates a mutating iterator for a map.
365 *
366 * The elements of the iterator are key/value pairs of type CxMapEntry and the pointer returned
367 * during iterator shall be treated as @c const @c CxMapEntry* .
368 *
369 * @note An iterator iterates over all elements successively. Therefore, the order
370 * highly depends on the map implementation and may change arbitrarily when the contents change.
371 *
372 * @param map the map to create the iterator for
373 * @return an iterator for the currently stored entries
374 * @see cxMapMutIteratorKeys()
375 * @see cxMapMutIteratorValues()
376 */
377 cx_attr_nonnull
378 cx_attr_nodiscard
379 cx_attr_export
380 CxMapIterator cxMapMutIterator(CxMap *map);
381
382 #ifdef __cplusplus
383 } // end the extern "C" block here, because we want to start overloading
384 cx_attr_nonnull
385 static inline int cxMapPut(
386 CxMap *map,
387 CxHashKey const &key,
388 void *value
389 ) {
390 return map->cl->put(map, key, value);
391 }
392
393 cx_attr_nonnull
394 static inline int cxMapPut(
395 CxMap *map,
396 cxstring const &key,
397 void *value
398 ) {
399 return map->cl->put(map, cx_hash_key_cxstr(key), value);
400 }
401
402 cx_attr_nonnull
403 static inline int cxMapPut(
404 CxMap *map,
405 cxmutstr const &key,
406 void *value
407 ) {
408 return map->cl->put(map, cx_hash_key_cxstr(key), value);
409 }
410
411 cx_attr_nonnull
412 cx_attr_cstr_arg(2)
413 static inline int cxMapPut(
414 CxMap *map,
415 const char *key,
416 void *value
417 ) {
418 return map->cl->put(map, cx_hash_key_str(key), value);
419 }
420
421 cx_attr_nonnull
422 cx_attr_nodiscard
423 static inline void *cxMapGet(
424 const CxMap *map,
425 CxHashKey const &key
426 ) {
427 return map->cl->get(map, key);
428 }
429
430 cx_attr_nonnull
431 cx_attr_nodiscard
432 static inline void *cxMapGet(
433 const CxMap *map,
434 cxstring const &key
435 ) {
436 return map->cl->get(map, cx_hash_key_cxstr(key));
437 }
438
439 cx_attr_nonnull
440 cx_attr_nodiscard
441 static inline void *cxMapGet(
442 const CxMap *map,
443 cxmutstr const &key
444 ) {
445 return map->cl->get(map, cx_hash_key_cxstr(key));
446 }
447
448 cx_attr_nonnull
449 cx_attr_nodiscard
450 cx_attr_cstr_arg(2)
451 static inline void *cxMapGet(
452 const CxMap *map,
453 const char *key
454 ) {
455 return map->cl->get(map, cx_hash_key_str(key));
456 }
457
458 cx_attr_nonnull
459 static inline int cxMapRemove(
460 CxMap *map,
461 CxHashKey const &key
462 ) {
463 return map->cl->remove(map, key, nullptr);
464 }
465
466 cx_attr_nonnull
467 static inline int cxMapRemove(
468 CxMap *map,
469 cxstring const &key
470 ) {
471 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
472 }
473
474 cx_attr_nonnull
475 static inline int cxMapRemove(
476 CxMap *map,
477 cxmutstr const &key
478 ) {
479 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
480 }
481
482 cx_attr_nonnull
483 cx_attr_cstr_arg(2)
484 static inline int cxMapRemove(
485 CxMap *map,
486 const char *key
487 ) {
488 return map->cl->remove(map, cx_hash_key_str(key), nullptr);
489 }
490
491 cx_attr_nonnull
492 cx_attr_access_w(3)
493 static inline int cxMapRemoveAndGet(
494 CxMap *map,
495 CxHashKey key,
496 void *targetbuf
497 ) {
498 return map->cl->remove(map, key, targetbuf);
499 }
500
501 cx_attr_nonnull
502 cx_attr_access_w(3)
503 static inline int cxMapRemoveAndGet(
504 CxMap *map,
505 cxstring key,
506 void *targetbuf
507 ) {
508 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
509 }
510
511 cx_attr_nonnull
512 cx_attr_access_w(3)
513 static inline int cxMapRemoveAndGet(
514 CxMap *map,
515 cxmutstr key,
516 void *targetbuf
517 ) {
518 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
519 }
520
521 cx_attr_nonnull
522 cx_attr_access_w(3)
523 cx_attr_cstr_arg(2)
524 static inline int cxMapRemoveAndGet(
525 CxMap *map,
526 const char *key,
527 void *targetbuf
528 ) {
529 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
530 }
531
532 #else // __cplusplus
533
534 /**
535 * @copydoc cxMapPut()
536 */
537 cx_attr_nonnull
538 static inline int cx_map_put(
539 CxMap *map,
540 CxHashKey key,
541 void *value
542 ) {
543 return map->cl->put(map, key, value);
544 }
545
546 /**
547 * @copydoc cxMapPut()
548 */
549 cx_attr_nonnull
550 static inline int cx_map_put_cxstr(
551 CxMap *map,
552 cxstring key,
553 void *value
554 ) {
555 return map->cl->put(map, cx_hash_key_cxstr(key), value);
556 }
557
558 /**
559 * @copydoc cxMapPut()
560 */
561 cx_attr_nonnull
562 static inline int cx_map_put_mustr(
563 CxMap *map,
564 cxmutstr key,
565 void *value
566 ) {
567 return map->cl->put(map, cx_hash_key_cxstr(key), value);
568 }
569
570 /**
571 * @copydoc cxMapPut()
572 */
573 cx_attr_nonnull
574 cx_attr_cstr_arg(2)
575 static inline int cx_map_put_str(
576 CxMap *map,
577 const char *key,
578 void *value
579 ) {
580 return map->cl->put(map, cx_hash_key_str(key), value);
581 }
582 299
583 /** 300 /**
584 * Puts a key/value-pair into the map. 301 * Puts a key/value-pair into the map.
585 * 302 *
586 * A possible existing value will be overwritten. 303 * A possible existing value will be overwritten.
591 * to the map. Otherwise, the memory is copied from @p value with 308 * to the map. Otherwise, the memory is copied from @p value with
592 * memcpy(). 309 * memcpy().
593 * 310 *
594 * The @p key is always copied. 311 * The @p key is always copied.
595 * 312 *
313 * @param map the map
314 * @param key the key
315 * @param value the value
316 * @retval zero success
317 * @retval non-zero value on memory allocation failure
318 * @see cxMapPut()
319 */
320 cx_attr_nonnull
321 CX_EXPORT int cx_map_put(CxMap *map, CxHashKey key, void *value);
322
323 /**
324 * Puts a key/value-pair into the map.
325 *
326 * A possible existing value will be overwritten.
327 * If destructor functions are specified, they are called for
328 * the overwritten element.
329 *
330 * If this map is storing pointers, the @p value pointer is written
331 * to the map. Otherwise, the memory is copied from @p value with
332 * memcpy().
333 *
334 * The @p key is always copied.
335 *
596 * @param map (@c CxMap*) the map 336 * @param map (@c CxMap*) the map
597 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key 337 * @param key (any supported key type) the key
598 * @param value (@c void*) the value 338 * @param value (@c void*) the value
599 * @retval zero success 339 * @retval zero success
600 * @retval non-zero value on memory allocation failure 340 * @retval non-zero value on memory allocation failure
601 */ 341 * @see CX_HASH_KEY()
602 #define cxMapPut(map, key, value) _Generic((key), \ 342 */
603 CxHashKey: cx_map_put, \ 343 #define cxMapPut(map, key, value) cx_map_put(map, CX_HASH_KEY(key), value)
604 cxstring: cx_map_put_cxstr, \ 344
605 cxmutstr: cx_map_put_mustr, \ 345 /**
606 char*: cx_map_put_str, \ 346 * Allocates memory for a value in the map associated with the specified key.
607 const char*: cx_map_put_str) \ 347 *
608 (map, key, value) 348 * A possible existing value will be overwritten.
609 349 * If destructor functions are specified, they are called for
610 /** 350 * the overwritten element.
611 * @copydoc cxMapGet() 351 *
352 * If the map is storing pointers, this function returns a @c void** pointer,
353 * meaning a pointer to that pointer.
354 *
355 * The @p key is always copied.
356 *
357 * @param map the map
358 * @param key the key
359 * @return the pointer to the allocated memory or @c NULL if allocation fails
360 * @retval zero success
361 * @retval non-zero value on memory allocation failure
362 * @see cxMapEmplace()
612 */ 363 */
613 cx_attr_nonnull 364 cx_attr_nonnull
614 cx_attr_nodiscard 365 CX_EXPORT void *cx_map_emplace(CxMap *map, CxHashKey key);
615 static inline void *cx_map_get( 366
616 const CxMap *map, 367 /**
617 CxHashKey key 368 * Allocates memory for a value in the map associated with the specified key.
618 ) { 369 *
619 return map->cl->get(map, key); 370 * A possible existing value will be overwritten.
620 } 371 * If destructor functions are specified, they are called for
621 372 * the overwritten element.
622 /** 373 *
623 * @copydoc cxMapGet() 374 * If the map is storing pointers, this function returns a @c void** pointer,
624 */ 375 * meaning a pointer to that pointer.
625 cx_attr_nonnull 376 *
626 cx_attr_nodiscard 377 * The @p key is always copied.
627 static inline void *cx_map_get_cxstr( 378 *
628 const CxMap *map, 379 * @param map (@c CxMap*) the map
629 cxstring key 380 * @param key (any supported key type) the key
630 ) { 381 * @return the pointer to the allocated memory or @c NULL if allocation fails
631 return map->cl->get(map, cx_hash_key_cxstr(key)); 382 * @retval zero success
632 } 383 * @retval non-zero value on memory allocation failure
633 384 * @see CX_HASH_KEY()
634 /** 385 */
635 * @copydoc cxMapGet() 386 #define cxMapEmplace(map, key) cx_map_emplace(map, CX_HASH_KEY(key))
636 */
637 cx_attr_nonnull
638 cx_attr_nodiscard
639 static inline void *cx_map_get_mustr(
640 const CxMap *map,
641 cxmutstr key
642 ) {
643 return map->cl->get(map, cx_hash_key_cxstr(key));
644 }
645
646 /**
647 * @copydoc cxMapGet()
648 */
649 cx_attr_nonnull
650 cx_attr_nodiscard
651 cx_attr_cstr_arg(2)
652 static inline void *cx_map_get_str(
653 const CxMap *map,
654 const char *key
655 ) {
656 return map->cl->get(map, cx_hash_key_str(key));
657 }
658 387
659 /** 388 /**
660 * Retrieves a value by using a key. 389 * Retrieves a value by using a key.
661 * 390 *
662 * If this map is storing pointers, the stored pointer is returned. 391 * If this map is storing pointers, the stored pointer is returned.
663 * Otherwise, a pointer to the element within the map's memory 392 * Otherwise, a pointer to the element within the map's memory
664 * is returned (which is valid as long as the element stays in the map). 393 * is returned (which is valid as long as the element stays in the map).
665 * 394 *
395 * @param map the map
396 * @param key the key
397 * @return the value
398 * @see cxMapGet()
399 */
400 cx_attr_nonnull cx_attr_nodiscard
401 CX_EXPORT void *cx_map_get(const CxMap *map, CxHashKey key);
402
403 /**
404 * Retrieves a value by using a key.
405 *
406 * If this map is storing pointers, the stored pointer is returned.
407 * Otherwise, a pointer to the element within the map's memory
408 * is returned (which is valid as long as the element stays in the map).
409 *
666 * @param map (@c CxMap*) the map 410 * @param map (@c CxMap*) the map
667 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key 411 * @param key (any supported key type) the key
668 * @return (@c void*) the value 412 * @return (@c void*) the value or @c NULL when no value with that @p key exists
669 */ 413 * @see CX_HASH_KEY()
670 #define cxMapGet(map, key) _Generic((key), \ 414 */
671 CxHashKey: cx_map_get, \ 415 #define cxMapGet(map, key) cx_map_get(map, CX_HASH_KEY(key))
672 cxstring: cx_map_get_cxstr, \ 416
673 cxmutstr: cx_map_get_mustr, \ 417 /**
674 char*: cx_map_get_str, \ 418 * Checks if a map contains a specific key.
675 const char*: cx_map_get_str) \ 419 *
676 (map, key) 420 * @param map (@c CxMap*) the map
677 421 * @param key (any supported key type) the key
678 /** 422 * @retval true if the key exists in the map
679 * @copydoc cxMapRemove() 423 * @retval false if the key does not exist in the map
680 */ 424 * @see CX_HASH_KEY()
681 cx_attr_nonnull 425 */
682 static inline int cx_map_remove( 426 #define cxMapContains(map, key) (cxMapGet(map, key) != NULL)
683 CxMap *map,
684 CxHashKey key
685 ) {
686 return map->cl->remove(map, key, NULL);
687 }
688
689 /**
690 * @copydoc cxMapRemove()
691 */
692 cx_attr_nonnull
693 static inline int cx_map_remove_cxstr(
694 CxMap *map,
695 cxstring key
696 ) {
697 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
698 }
699
700 /**
701 * @copydoc cxMapRemove()
702 */
703 cx_attr_nonnull
704 static inline int cx_map_remove_mustr(
705 CxMap *map,
706 cxmutstr key
707 ) {
708 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
709 }
710
711 /**
712 * @copydoc cxMapRemove()
713 */
714 cx_attr_nonnull
715 cx_attr_cstr_arg(2)
716 static inline int cx_map_remove_str(
717 CxMap *map,
718 const char *key
719 ) {
720 return map->cl->remove(map, cx_hash_key_str(key), NULL);
721 }
722 427
723 /** 428 /**
724 * Removes a key/value-pair from the map by using the key. 429 * Removes a key/value-pair from the map by using the key.
725 * 430 *
726 * Always invokes the destructors functions, if any, on the removed element. 431 * Invokes the destructor functions, if any, on the removed element if and only if the
432 * @p targetbuf is @c NULL.
433 *
434 * @param map the map
435 * @param key the key
436 * @param targetbuf the optional buffer where the removed element shall be copied to
437 * @retval zero success
438 * @retval non-zero the key was not found
439 *
440 * @see cxMapRemove()
441 * @see cxMapRemoveAndGet()
442 */
443 cx_attr_nonnull_arg(1)
444 CX_EXPORT int cx_map_remove(CxMap *map, CxHashKey key, void *targetbuf);
445
446 /**
447 * Removes a key/value-pair from the map by using the key.
448 *
449 * Always invokes the destructor functions, if any, on the removed element.
727 * 450 *
728 * @param map (@c CxMap*) the map 451 * @param map (@c CxMap*) the map
729 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key 452 * @param key (any supported key type) the key
730 * @retval zero success 453 * @retval zero success
731 * @retval non-zero the key was not found 454 * @retval non-zero the key was not found
732 * 455 *
733 * @see cxMapRemoveAndGet() 456 * @see cxMapRemoveAndGet()
734 */ 457 * @see CX_HASH_KEY()
735 #define cxMapRemove(map, key) _Generic((key), \ 458 */
736 CxHashKey: cx_map_remove, \ 459 #define cxMapRemove(map, key) cx_map_remove(map, CX_HASH_KEY(key), NULL)
737 cxstring: cx_map_remove_cxstr, \
738 cxmutstr: cx_map_remove_mustr, \
739 char*: cx_map_remove_str, \
740 const char*: cx_map_remove_str) \
741 (map, key)
742
743 /**
744 * @copydoc cxMapRemoveAndGet()
745 */
746 cx_attr_nonnull
747 cx_attr_access_w(3)
748 static inline int cx_map_remove_and_get(
749 CxMap *map,
750 CxHashKey key,
751 void *targetbuf
752 ) {
753 return map->cl->remove(map, key, targetbuf);
754 }
755
756 /**
757 * @copydoc cxMapRemoveAndGet()
758 */
759 cx_attr_nonnull
760 cx_attr_access_w(3)
761 static inline int cx_map_remove_and_get_cxstr(
762 CxMap *map,
763 cxstring key,
764 void *targetbuf
765 ) {
766 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
767 }
768
769 /**
770 * @copydoc cxMapRemoveAndGet()
771 */
772 cx_attr_nonnull
773 cx_attr_access_w(3)
774 static inline int cx_map_remove_and_get_mustr(
775 CxMap *map,
776 cxmutstr key,
777 void *targetbuf
778 ) {
779 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
780 }
781
782 /**
783 * @copydoc cxMapRemoveAndGet()
784 */
785 cx_attr_nonnull
786 cx_attr_access_w(3)
787 cx_attr_cstr_arg(2)
788 static inline int cx_map_remove_and_get_str(
789 CxMap *map,
790 const char *key,
791 void *targetbuf
792 ) {
793 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
794 }
795 460
796 /** 461 /**
797 * Removes a key/value-pair from the map by using the key. 462 * Removes a key/value-pair from the map by using the key.
798 * 463 *
799 * This function will copy the contents of the removed element 464 * This function will copy the contents of the removed element
803 * 468 *
804 * If this map is storing pointers, the element is the pointer itself 469 * If this map is storing pointers, the element is the pointer itself
805 * and not the object it points to. 470 * and not the object it points to.
806 * 471 *
807 * @param map (@c CxMap*) the map 472 * @param map (@c CxMap*) the map
808 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key 473 * @param key (any supported key type) the key
809 * @param targetbuf (@c void*) the buffer where the element shall be copied to 474 * @param targetbuf (@c void*) the buffer where the element shall be copied to
810 * @retval zero success 475 * @retval zero success
811 * @retval non-zero the key was not found 476 * @retval non-zero the key was not found
812 * 477 *
813 * @see cxMapRemove() 478 * @see cxMapRemove()
814 */ 479 * @see CX_HASH_KEY()
815 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \ 480 */
816 CxHashKey: cx_map_remove_and_get, \ 481 #define cxMapRemoveAndGet(map, key, targetbuf) cx_map_remove(map, CX_HASH_KEY(key), targetbuf)
817 cxstring: cx_map_remove_and_get_cxstr, \ 482
818 cxmutstr: cx_map_remove_and_get_mustr, \ 483
819 char*: cx_map_remove_and_get_str, \ 484 /**
820 const char*: cx_map_remove_and_get_str) \ 485 * Performs a deep clone of one map into another.
821 (map, key, targetbuf) 486 *
822 487 * If the destination map already contains entries, the cloned entries
823 #endif // __cplusplus 488 * are added to that map, possibly overwriting existing elements when
489 * the keys already exist.
490 *
491 * When elements in the destination map need to be replaced, any destructor
492 * function is called on the replaced elements before replacing them.
493 *
494 * @attention If the cloned elements need to be destroyed by a destructor
495 * function, you must make sure that the destination map also uses this
496 * destructor function.
497 *
498 * @param dst the destination map
499 * @param src the source map
500 * @param clone_func the clone function for the values
501 * @param clone_allocator the allocator that is passed to the clone function
502 * @param data optional additional data that is passed to the clone function
503 * @retval zero when all elements were successfully cloned
504 * @retval non-zero when an allocation error occurred
505 */
506 cx_attr_nonnull_arg(1, 2, 3)
507 CX_EXPORT int cxMapClone(CxMap *dst, const CxMap *src,
508 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
509
510
511 /**
512 * Clones entries of a map if their key is not present in another map.
513 *
514 * @param dst the destination map
515 * @param minuend the map to subtract the entries from
516 * @param subtrahend the map containing the elements to be subtracted
517 * @param clone_func the clone function for the values
518 * @param clone_allocator the allocator that is passed to the clone function
519 * @param data optional additional data that is passed to the clone function
520 * @retval zero when the elements were successfully cloned
521 * @retval non-zero when an allocation error occurred
522 */
523 cx_attr_nonnull_arg(1, 2, 3, 4)
524 CX_EXPORT int cxMapDifference(CxMap *dst, const CxMap *minuend, const CxMap *subtrahend,
525 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
526
527 /**
528 * Clones entries of a map if their key is not present in a list.
529 *
530 * Note that the list must contain keys of type @c CxKey
531 * (or pointers to such keys) and must use @c cx_hash_key_cmp
532 * as the compare function.
533 * Generic key types cannot be processed in this case.
534 *
535 * @param dst the destination map
536 * @param src the source map
537 * @param keys the list of @c CxKey items
538 * @param clone_func the clone function for the values
539 * @param clone_allocator the allocator that is passed to the clone function
540 * @param data optional additional data that is passed to the clone function
541 * @retval zero when the elements were successfully cloned
542 * @retval non-zero when an allocation error occurred
543 */
544 cx_attr_nonnull_arg(1, 2, 3, 4)
545 CX_EXPORT int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys,
546 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
547
548
549 /**
550 * Clones entries of a map only if their key is present in another map.
551 *
552 * @param dst the destination map
553 * @param src the map to clone the entries from
554 * @param other the map to check for existence of the keys
555 * @param clone_func the clone function for the values
556 * @param clone_allocator the allocator that is passed to the clone function
557 * @param data optional additional data that is passed to the clone function
558 * @retval zero when the elements were successfully cloned
559 * @retval non-zero when an allocation error occurred
560 */
561 cx_attr_nonnull_arg(1, 2, 3, 4)
562 CX_EXPORT int cxMapIntersection(CxMap *dst, const CxMap *src, const CxMap *other,
563 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
564
565 /**
566 * Clones entries of a map only if their key is present in a list.
567 *
568 * Note that the list must contain keys of type @c CxKey
569 * (or pointers to such keys) and must use @c cx_hash_key_cmp
570 * as the compare function.
571 * Generic key types cannot be processed in this case.
572 *
573 * @param dst the destination map
574 * @param src the source map
575 * @param keys the list of @c CxKey items
576 * @param clone_func the clone function for the values
577 * @param clone_allocator the allocator that is passed to the clone function
578 * @param data optional additional data that is passed to the clone function
579 * @retval zero when the elements were successfully cloned
580 * @retval non-zero when an allocation error occurred
581 */
582 cx_attr_nonnull_arg(1, 2, 3, 4)
583 CX_EXPORT int cxMapListIntersection(CxMap *dst, const CxMap *src, const CxList *keys,
584 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
585
586 /**
587 * Clones entries into a map if their key does not exist yet.
588 *
589 * If you want to calculate the union of two maps into a fresh new map,
590 * you can proceed as follows:
591 * 1. Clone the first map into a fresh, empty map.
592 * 2. Use this function to clone the second map into the result from step 1.
593 *
594 * @param dst the destination map
595 * @param src the map to clone the entries from
596 * @param clone_func the clone function for the values
597 * @param clone_allocator the allocator that is passed to the clone function
598 * @param data optional additional data that is passed to the clone function
599 * @retval zero when the elements were successfully cloned
600 * @retval non-zero when an allocation error occurred
601 */
602 cx_attr_nonnull_arg(1, 2, 3)
603 CX_EXPORT int cxMapUnion(CxMap *dst, const CxMap *src,
604 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
605
606 #ifdef __cplusplus
607 } // extern "C"
608 #endif
824 609
825 #endif // UCX_MAP_H 610 #endif // UCX_MAP_H

mercurial