ucx/cx/map.h

changeset 852
83fdf679df99
parent 816
839fefbdedc7
equal deleted inserted replaced
850:bbe2925eb590 852:83fdf679df99
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 /** 28 /**
29 * \file map.h 29 * @file map.h
30 * \brief Interface for map implementations. 30 * @brief Interface for map implementations.
31 * \author Mike Becker 31 * @author Mike Becker
32 * \author Olaf Wintermann 32 * @author Olaf Wintermann
33 * \copyright 2-Clause BSD License 33 * @copyright 2-Clause BSD License
34 */ 34 */
35 35
36 #ifndef UCX_MAP_H 36 #ifndef UCX_MAP_H
37 #define UCX_MAP_H 37 #define UCX_MAP_H
38 38
87 */ 87 */
88 struct cx_map_class_s { 88 struct cx_map_class_s {
89 /** 89 /**
90 * Deallocates the entire memory. 90 * Deallocates the entire memory.
91 */ 91 */
92 __attribute__((__nonnull__)) 92 void (*deallocate)(struct cx_map_s *map);
93 void (*destructor)(struct cx_map_s *map);
94 93
95 /** 94 /**
96 * Removes all elements. 95 * Removes all elements.
97 */ 96 */
98 __attribute__((__nonnull__))
99 void (*clear)(struct cx_map_s *map); 97 void (*clear)(struct cx_map_s *map);
100 98
101 /** 99 /**
102 * Add or overwrite an element. 100 * Add or overwrite an element.
103 */ 101 */
104 __attribute__((__nonnull__))
105 int (*put)( 102 int (*put)(
106 CxMap *map, 103 CxMap *map,
107 CxHashKey key, 104 CxHashKey key,
108 void *value 105 void *value
109 ); 106 );
110 107
111 /** 108 /**
112 * Returns an element. 109 * Returns an element.
113 */ 110 */
114 __attribute__((__nonnull__, __warn_unused_result__))
115 void *(*get)( 111 void *(*get)(
116 CxMap const *map, 112 const CxMap *map,
117 CxHashKey key 113 CxHashKey key
118 ); 114 );
119 115
120 /** 116 /**
121 * Removes an element. 117 * Removes an element.
122 */ 118 *
123 __attribute__((__nonnull__)) 119 * Implementations SHALL check if @p targetbuf is set and copy the elements
124 void *(*remove)( 120 * to the buffer without invoking any destructor.
121 * When @p targetbuf is not set, the destructors SHALL be invoked.
122 *
123 * The function SHALL return zero when the @p key was found and
124 * non-zero, otherwise.
125 */
126 int (*remove)(
125 CxMap *map, 127 CxMap *map,
126 CxHashKey key, 128 CxHashKey key,
127 bool destroy 129 void *targetbuf
128 ); 130 );
129 131
130 /** 132 /**
131 * Creates an iterator for this map. 133 * Creates an iterator for this map.
132 */ 134 */
133 __attribute__((__nonnull__, __warn_unused_result__)) 135 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
134 CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
135 }; 136 };
136 137
137 /** 138 /**
138 * A map entry. 139 * A map entry.
139 */ 140 */
140 struct cx_map_entry_s { 141 struct cx_map_entry_s {
141 /** 142 /**
142 * A pointer to the key. 143 * A pointer to the key.
143 */ 144 */
144 CxHashKey const *key; 145 const CxHashKey *key;
145 /** 146 /**
146 * A pointer to the value. 147 * A pointer to the value.
147 */ 148 */
148 void *value; 149 void *value;
149 }; 150 };
150 151
151 /** 152 /**
152 * A shared instance of an empty map. 153 * A shared instance of an empty map.
153 * 154 *
154 * Writing to that map is undefined. 155 * Writing to that map is not allowed.
156 *
157 * You can use this is a placeholder for initializing CxMap pointers
158 * for which you do not want to reserve memory right from the beginning.
155 */ 159 */
156 extern CxMap *const cxEmptyMap; 160 extern CxMap *const cxEmptyMap;
157 161
158 /** 162 /**
159 * Advises the map to store copies of the objects (default mode of operation). 163 * Advises the map to store copies of the objects (default mode of operation).
162 * within this list. 166 * within this list.
163 * 167 *
164 * @param map the map 168 * @param map the map
165 * @see cxMapStorePointers() 169 * @see cxMapStorePointers()
166 */ 170 */
167 __attribute__((__nonnull__)) 171 cx_attr_nonnull
168 static inline void cxMapStoreObjects(CxMap *map) { 172 static inline void cxMapStoreObjects(CxMap *map) {
169 map->collection.store_pointer = false; 173 map->collection.store_pointer = false;
170 } 174 }
171 175
172 /** 176 /**
179 * objects is undefined. 183 * objects is undefined.
180 * 184 *
181 * @param map the map 185 * @param map the map
182 * @see cxMapStoreObjects() 186 * @see cxMapStoreObjects()
183 */ 187 */
184 __attribute__((__nonnull__)) 188 cx_attr_nonnull
185 static inline void cxMapStorePointers(CxMap *map) { 189 static inline void cxMapStorePointers(CxMap *map) {
186 map->collection.store_pointer = true; 190 map->collection.store_pointer = true;
187 map->collection.elem_size = sizeof(void *); 191 map->collection.elem_size = sizeof(void *);
188 } 192 }
189 193
192 * 196 *
193 * @param map 197 * @param map
194 * @return true, if this map is storing pointers 198 * @return true, if this map is storing pointers
195 * @see cxMapStorePointers() 199 * @see cxMapStorePointers()
196 */ 200 */
197 __attribute__((__nonnull__)) 201 cx_attr_nonnull
198 static inline bool cxMapIsStoringPointers(CxMap const *map) { 202 static inline bool cxMapIsStoringPointers(const CxMap *map) {
199 return map->collection.store_pointer; 203 return map->collection.store_pointer;
200 } 204 }
201 205
202 /** 206 /**
203 * Deallocates the memory of the specified map. 207 * Deallocates the memory of the specified map.
204 * 208 *
205 * @param map the map to be destroyed 209 * Also calls the content destructor functions for each element, if specified.
206 */ 210 *
207 __attribute__((__nonnull__)) 211 * @param map the map to be freed
208 static inline void cxMapDestroy(CxMap *map) { 212 */
209 map->cl->destructor(map); 213 void cxMapFree(CxMap *map);
210 }
211 214
212 215
213 /** 216 /**
214 * Clears a map by removing all elements. 217 * Clears a map by removing all elements.
215 * 218 *
219 * Also calls the content destructor functions for each element, if specified.
220 *
216 * @param map the map to be cleared 221 * @param map the map to be cleared
217 */ 222 */
218 __attribute__((__nonnull__)) 223 cx_attr_nonnull
219 static inline void cxMapClear(CxMap *map) { 224 static inline void cxMapClear(CxMap *map) {
220 map->cl->clear(map); 225 map->cl->clear(map);
221 } 226 }
222 227
223 /** 228 /**
224 * Returns the number of elements in this map. 229 * Returns the number of elements in this map.
225 * 230 *
226 * @param map the map 231 * @param map the map
227 * @return the number of stored elements 232 * @return the number of stored elements
228 */ 233 */
229 __attribute__((__nonnull__)) 234 cx_attr_nonnull
230 static inline size_t cxMapSize(CxMap const *map) { 235 static inline size_t cxMapSize(const CxMap *map) {
231 return map->collection.size; 236 return map->collection.size;
232 } 237 }
233 238
234
235 // TODO: set-like map operations (union, intersect, difference)
236
237 /** 239 /**
238 * Creates a value iterator for a map. 240 * Creates a value iterator for a map.
239 * 241 *
240 * \note An iterator iterates over all elements successively. Therefore the order 242 * @note An iterator iterates over all elements successively. Therefore, the order
241 * highly depends on the map implementation and may change arbitrarily when the contents change. 243 * highly depends on the map implementation and may change arbitrarily when the contents change.
242 * 244 *
243 * @param map the map to create the iterator for 245 * @param map the map to create the iterator for
244 * @return an iterator for the currently stored values 246 * @return an iterator for the currently stored values
245 */ 247 */
246 __attribute__((__nonnull__, __warn_unused_result__)) 248 cx_attr_nonnull
247 static inline CxIterator cxMapIteratorValues(CxMap const *map) { 249 cx_attr_nodiscard
250 static inline CxIterator cxMapIteratorValues(const CxMap *map) {
248 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES); 251 return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
249 } 252 }
250 253
251 /** 254 /**
252 * Creates a key iterator for a map. 255 * Creates a key iterator for a map.
253 * 256 *
254 * The elements of the iterator are keys of type CxHashKey. 257 * The elements of the iterator are keys of type CxHashKey.
255 * 258 *
256 * \note An iterator iterates over all elements successively. Therefore the order 259 * @note An iterator iterates over all elements successively. Therefore, the order
257 * 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.
258 * 261 *
259 * @param map the map to create the iterator for 262 * @param map the map to create the iterator for
260 * @return an iterator for the currently stored keys 263 * @return an iterator for the currently stored keys
261 */ 264 */
262 __attribute__((__nonnull__, __warn_unused_result__)) 265 cx_attr_nonnull
263 static inline CxIterator cxMapIteratorKeys(CxMap const *map) { 266 cx_attr_nodiscard
267 static inline CxIterator cxMapIteratorKeys(const CxMap *map) {
264 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS); 268 return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
265 } 269 }
266 270
267 /** 271 /**
268 * Creates an iterator for a map. 272 * Creates an iterator for a map.
269 * 273 *
270 * The elements of the iterator are key/value pairs of type CxMapEntry. 274 * The elements of the iterator are key/value pairs of type CxMapEntry.
271 * 275 *
272 * \note An iterator iterates over all elements successively. Therefore the order 276 * @note An iterator iterates over all elements successively. Therefore, the order
273 * highly depends on the map implementation and may change arbitrarily when the contents change. 277 * highly depends on the map implementation and may change arbitrarily when the contents change.
274 * 278 *
275 * @param map the map to create the iterator for 279 * @param map the map to create the iterator for
276 * @return an iterator for the currently stored entries 280 * @return an iterator for the currently stored entries
277 * @see cxMapIteratorKeys() 281 * @see cxMapIteratorKeys()
278 * @see cxMapIteratorValues() 282 * @see cxMapIteratorValues()
279 */ 283 */
280 __attribute__((__nonnull__, __warn_unused_result__)) 284 cx_attr_nonnull
281 static inline CxIterator cxMapIterator(CxMap const *map) { 285 cx_attr_nodiscard
286 static inline CxIterator cxMapIterator(const CxMap *map) {
282 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS); 287 return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
283 } 288 }
284 289
285 290
286 /** 291 /**
287 * Creates a mutating iterator over the values of a map. 292 * Creates a mutating iterator over the values of a map.
288 * 293 *
289 * \note An iterator iterates over all elements successively. Therefore the order 294 * @note An iterator iterates over all elements successively. Therefore, the order
290 * highly depends on the map implementation and may change arbitrarily when the contents change. 295 * highly depends on the map implementation and may change arbitrarily when the contents change.
291 * 296 *
292 * @param map the map to create the iterator for 297 * @param map the map to create the iterator for
293 * @return an iterator for the currently stored values 298 * @return an iterator for the currently stored values
294 */ 299 */
295 __attribute__((__nonnull__, __warn_unused_result__)) 300 cx_attr_nonnull
301 cx_attr_nodiscard
296 CxIterator cxMapMutIteratorValues(CxMap *map); 302 CxIterator cxMapMutIteratorValues(CxMap *map);
297 303
298 /** 304 /**
299 * Creates a mutating iterator over the keys of a map. 305 * Creates a mutating iterator over the keys of a map.
300 * 306 *
301 * The elements of the iterator are keys of type CxHashKey. 307 * The elements of the iterator are keys of type CxHashKey.
302 * 308 *
303 * \note An iterator iterates over all elements successively. Therefore the order 309 * @note An iterator iterates over all elements successively. Therefore, the order
304 * highly depends on the map implementation and may change arbitrarily when the contents change. 310 * highly depends on the map implementation and may change arbitrarily when the contents change.
305 * 311 *
306 * @param map the map to create the iterator for 312 * @param map the map to create the iterator for
307 * @return an iterator for the currently stored keys 313 * @return an iterator for the currently stored keys
308 */ 314 */
309 __attribute__((__nonnull__, __warn_unused_result__)) 315 cx_attr_nonnull
316 cx_attr_nodiscard
310 CxIterator cxMapMutIteratorKeys(CxMap *map); 317 CxIterator cxMapMutIteratorKeys(CxMap *map);
311 318
312 /** 319 /**
313 * Creates a mutating iterator for a map. 320 * Creates a mutating iterator for a map.
314 * 321 *
315 * The elements of the iterator are key/value pairs of type CxMapEntry. 322 * The elements of the iterator are key/value pairs of type CxMapEntry.
316 * 323 *
317 * \note An iterator iterates over all elements successively. Therefore the order 324 * @note An iterator iterates over all elements successively. Therefore, the order
318 * highly depends on the map implementation and may change arbitrarily when the contents change. 325 * highly depends on the map implementation and may change arbitrarily when the contents change.
319 * 326 *
320 * @param map the map to create the iterator for 327 * @param map the map to create the iterator for
321 * @return an iterator for the currently stored entries 328 * @return an iterator for the currently stored entries
322 * @see cxMapMutIteratorKeys() 329 * @see cxMapMutIteratorKeys()
323 * @see cxMapMutIteratorValues() 330 * @see cxMapMutIteratorValues()
324 */ 331 */
325 __attribute__((__nonnull__, __warn_unused_result__)) 332 cx_attr_nonnull
333 cx_attr_nodiscard
326 CxIterator cxMapMutIterator(CxMap *map); 334 CxIterator cxMapMutIterator(CxMap *map);
327 335
328 #ifdef __cplusplus 336 #ifdef __cplusplus
329 } // end the extern "C" block here, because we want to start overloading 337 } // end the extern "C" block here, because we want to start overloading
330 338 cx_attr_nonnull
331 /**
332 * Puts a key/value-pair into the map.
333 *
334 * @param map the map
335 * @param key the key
336 * @param value the value
337 * @return 0 on success, non-zero value on failure
338 */
339 __attribute__((__nonnull__))
340 static inline int cxMapPut( 339 static inline int cxMapPut(
341 CxMap *map, 340 CxMap *map,
342 CxHashKey const &key, 341 CxHashKey const &key,
343 void *value 342 void *value
344 ) { 343 ) {
345 return map->cl->put(map, key, value); 344 return map->cl->put(map, key, value);
346 } 345 }
347 346
348 347 cx_attr_nonnull
349 /**
350 * Puts a key/value-pair into the map.
351 *
352 * @param map the map
353 * @param key the key
354 * @param value the value
355 * @return 0 on success, non-zero value on failure
356 */
357 __attribute__((__nonnull__))
358 static inline int cxMapPut( 348 static inline int cxMapPut(
359 CxMap *map, 349 CxMap *map,
360 cxstring const &key, 350 cxstring const &key,
361 void *value 351 void *value
362 ) { 352 ) {
363 return map->cl->put(map, cx_hash_key_cxstr(key), value); 353 return map->cl->put(map, cx_hash_key_cxstr(key), value);
364 } 354 }
365 355
366 /** 356 cx_attr_nonnull
367 * Puts a key/value-pair into the map.
368 *
369 * @param map the map
370 * @param key the key
371 * @param value the value
372 * @return 0 on success, non-zero value on failure
373 */
374 __attribute__((__nonnull__))
375 static inline int cxMapPut( 357 static inline int cxMapPut(
376 CxMap *map, 358 CxMap *map,
377 cxmutstr const &key, 359 cxmutstr const &key,
378 void *value 360 void *value
379 ) { 361 ) {
380 return map->cl->put(map, cx_hash_key_cxstr(key), value); 362 return map->cl->put(map, cx_hash_key_cxstr(key), value);
381 } 363 }
382 364
383 /** 365 cx_attr_nonnull
384 * Puts a key/value-pair into the map. 366 cx_attr_cstr_arg(2)
385 *
386 * @param map the map
387 * @param key the key
388 * @param value the value
389 * @return 0 on success, non-zero value on failure
390 */
391 __attribute__((__nonnull__))
392 static inline int cxMapPut( 367 static inline int cxMapPut(
393 CxMap *map, 368 CxMap *map,
394 char const *key, 369 const char *key,
395 void *value 370 void *value
396 ) { 371 ) {
397 return map->cl->put(map, cx_hash_key_str(key), value); 372 return map->cl->put(map, cx_hash_key_str(key), value);
398 } 373 }
399 374
400 /** 375 cx_attr_nonnull
401 * Retrieves a value by using a key. 376 cx_attr_nodiscard
402 *
403 * @param map the map
404 * @param key the key
405 * @return the value
406 */
407 __attribute__((__nonnull__, __warn_unused_result__))
408 static inline void *cxMapGet( 377 static inline void *cxMapGet(
409 CxMap const *map, 378 const CxMap *map,
410 CxHashKey const &key 379 CxHashKey const &key
411 ) { 380 ) {
412 return map->cl->get(map, key); 381 return map->cl->get(map, key);
413 } 382 }
414 383
415 /** 384 cx_attr_nonnull
416 * Retrieves a value by using a key. 385 cx_attr_nodiscard
417 *
418 * @param map the map
419 * @param key the key
420 * @return the value
421 */
422 __attribute__((__nonnull__, __warn_unused_result__))
423 static inline void *cxMapGet( 386 static inline void *cxMapGet(
424 CxMap const *map, 387 const CxMap *map,
425 cxstring const &key 388 cxstring const &key
426 ) { 389 ) {
427 return map->cl->get(map, cx_hash_key_cxstr(key)); 390 return map->cl->get(map, cx_hash_key_cxstr(key));
428 } 391 }
429 392
430 /** 393 cx_attr_nonnull
431 * Retrieves a value by using a key. 394 cx_attr_nodiscard
432 *
433 * @param map the map
434 * @param key the key
435 * @return the value
436 */
437 __attribute__((__nonnull__, __warn_unused_result__))
438 static inline void *cxMapGet( 395 static inline void *cxMapGet(
439 CxMap const *map, 396 const CxMap *map,
440 cxmutstr const &key 397 cxmutstr const &key
441 ) { 398 ) {
442 return map->cl->get(map, cx_hash_key_cxstr(key)); 399 return map->cl->get(map, cx_hash_key_cxstr(key));
443 } 400 }
444 401
445 /** 402 cx_attr_nonnull
446 * Retrieves a value by using a key. 403 cx_attr_nodiscard
447 * 404 cx_attr_cstr_arg(2)
448 * @param map the map
449 * @param key the key
450 * @return the value
451 */
452 __attribute__((__nonnull__, __warn_unused_result__))
453 static inline void *cxMapGet( 405 static inline void *cxMapGet(
454 CxMap const *map, 406 const CxMap *map,
455 char const *key 407 const char *key
456 ) { 408 ) {
457 return map->cl->get(map, cx_hash_key_str(key)); 409 return map->cl->get(map, cx_hash_key_str(key));
458 } 410 }
459 411
460 /** 412 cx_attr_nonnull
461 * Removes a key/value-pair from the map by using the key. 413 static inline int cxMapRemove(
462 *
463 * Always invokes the destructor function, if any, on the removed element.
464 * If this map is storing pointers and you just want to retrieve the pointer
465 * without invoking the destructor, use cxMapRemoveAndGet().
466 * If you just want to detach the element from the map without invoking the
467 * destructor or returning the element, use cxMapDetach().
468 *
469 * @param map the map
470 * @param key the key
471 * @see cxMapRemoveAndGet()
472 * @see cxMapDetach()
473 */
474 __attribute__((__nonnull__))
475 static inline void cxMapRemove(
476 CxMap *map, 414 CxMap *map,
477 CxHashKey const &key 415 CxHashKey const &key
478 ) { 416 ) {
479 (void) map->cl->remove(map, key, true); 417 return map->cl->remove(map, key, nullptr);
480 } 418 }
481 419
482 /** 420 cx_attr_nonnull
483 * Removes a key/value-pair from the map by using the key. 421 static inline int cxMapRemove(
484 *
485 * Always invokes the destructor function, if any, on the removed element.
486 * If this map is storing pointers and you just want to retrieve the pointer
487 * without invoking the destructor, use cxMapRemoveAndGet().
488 * If you just want to detach the element from the map without invoking the
489 * destructor or returning the element, use cxMapDetach().
490 *
491 * @param map the map
492 * @param key the key
493 * @see cxMapRemoveAndGet()
494 * @see cxMapDetach()
495 */
496 __attribute__((__nonnull__))
497 static inline void cxMapRemove(
498 CxMap *map, 422 CxMap *map,
499 cxstring const &key 423 cxstring const &key
500 ) { 424 ) {
501 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); 425 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
502 } 426 }
503 427
504 /** 428 cx_attr_nonnull
505 * Removes a key/value-pair from the map by using the key. 429 static inline int cxMapRemove(
506 *
507 * Always invokes the destructor function, if any, on the removed element.
508 * If this map is storing pointers and you just want to retrieve the pointer
509 * without invoking the destructor, use cxMapRemoveAndGet().
510 * If you just want to detach the element from the map without invoking the
511 * destructor or returning the element, use cxMapDetach().
512 *
513 * @param map the map
514 * @param key the key
515 * @see cxMapRemoveAndGet()
516 * @see cxMapDetach()
517 */
518 __attribute__((__nonnull__))
519 static inline void cxMapRemove(
520 CxMap *map, 430 CxMap *map,
521 cxmutstr const &key 431 cxmutstr const &key
522 ) { 432 ) {
523 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true); 433 return map->cl->remove(map, cx_hash_key_cxstr(key), nullptr);
524 } 434 }
525 435
526 /** 436 cx_attr_nonnull
527 * Removes a key/value-pair from the map by using the key. 437 cx_attr_cstr_arg(2)
528 * 438 static inline int cxMapRemove(
529 * Always invokes the destructor function, if any, on the removed element. 439 CxMap *map,
530 * If this map is storing pointers and you just want to retrieve the pointer 440 const char *key
531 * without invoking the destructor, use cxMapRemoveAndGet(). 441 ) {
532 * If you just want to detach the element from the map without invoking the 442 return map->cl->remove(map, cx_hash_key_str(key), nullptr);
533 * destructor or returning the element, use cxMapDetach(). 443 }
534 * 444
535 * @param map the map 445 cx_attr_nonnull
536 * @param key the key 446 cx_attr_access_w(3)
537 * @see cxMapRemoveAndGet() 447 static inline int cxMapRemoveAndGet(
538 * @see cxMapDetach() 448 CxMap *map,
539 */ 449 CxHashKey key,
540 __attribute__((__nonnull__)) 450 void *targetbuf
541 static inline void cxMapRemove( 451 ) {
542 CxMap *map, 452 return map->cl->remove(map, key, targetbuf);
543 char const *key 453 }
544 ) { 454
545 (void) map->cl->remove(map, cx_hash_key_str(key), true); 455 cx_attr_nonnull
546 } 456 cx_attr_access_w(3)
547 457 static inline int cxMapRemoveAndGet(
548 /** 458 CxMap *map,
549 * Detaches a key/value-pair from the map by using the key 459 cxstring key,
550 * without invoking the destructor. 460 void *targetbuf
551 * 461 ) {
552 * In general, you should only use this function if the map does not own 462 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
553 * the data and there is a valid reference to the data somewhere else 463 }
554 * in the program. In all other cases it is preferable to use 464
555 * cxMapRemove() or cxMapRemoveAndGet(). 465 cx_attr_nonnull
556 * 466 cx_attr_access_w(3)
557 * @param map the map 467 static inline int cxMapRemoveAndGet(
558 * @param key the key 468 CxMap *map,
559 * @see cxMapRemove() 469 cxmutstr key,
560 * @see cxMapRemoveAndGet() 470 void *targetbuf
561 */ 471 ) {
562 __attribute__((__nonnull__)) 472 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
563 static inline void cxMapDetach( 473 }
564 CxMap *map, 474
565 CxHashKey const &key 475 cx_attr_nonnull
566 ) { 476 cx_attr_access_w(3)
567 (void) map->cl->remove(map, key, false); 477 cx_attr_cstr_arg(2)
568 } 478 static inline int cxMapRemoveAndGet(
569 479 CxMap *map,
570 /** 480 const char *key,
571 * Detaches a key/value-pair from the map by using the key 481 void *targetbuf
572 * without invoking the destructor. 482 ) {
573 * 483 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
574 * In general, you should only use this function if the map does not own
575 * the data and there is a valid reference to the data somewhere else
576 * in the program. In all other cases it is preferable to use
577 * cxMapRemove() or cxMapRemoveAndGet().
578 *
579 * @param map the map
580 * @param key the key
581 * @see cxMapRemove()
582 * @see cxMapRemoveAndGet()
583 */
584 __attribute__((__nonnull__))
585 static inline void cxMapDetach(
586 CxMap *map,
587 cxstring const &key
588 ) {
589 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
590 }
591
592 /**
593 * Detaches a key/value-pair from the map by using the key
594 * without invoking the destructor.
595 *
596 * In general, you should only use this function if the map does not own
597 * the data and there is a valid reference to the data somewhere else
598 * in the program. In all other cases it is preferable to use
599 * cxMapRemove() or cxMapRemoveAndGet().
600 *
601 * @param map the map
602 * @param key the key
603 * @see cxMapRemove()
604 * @see cxMapRemoveAndGet()
605 */
606 __attribute__((__nonnull__))
607 static inline void cxMapDetach(
608 CxMap *map,
609 cxmutstr const &key
610 ) {
611 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
612 }
613
614 /**
615 * Detaches a key/value-pair from the map by using the key
616 * without invoking the destructor.
617 *
618 * In general, you should only use this function if the map does not own
619 * the data and there is a valid reference to the data somewhere else
620 * in the program. In all other cases it is preferable to use
621 * cxMapRemove() or cxMapRemoveAndGet().
622 *
623 * @param map the map
624 * @param key the key
625 * @see cxMapRemove()
626 * @see cxMapRemoveAndGet()
627 */
628 __attribute__((__nonnull__))
629 static inline void cxMapDetach(
630 CxMap *map,
631 char const *key
632 ) {
633 (void) map->cl->remove(map, cx_hash_key_str(key), false);
634 }
635
636 /**
637 * Removes a key/value-pair from the map by using the key.
638 *
639 * This function can be used when the map is storing pointers,
640 * in order to retrieve the pointer from the map without invoking
641 * any destructor function. Sometimes you do not want the pointer
642 * to be returned - in that case (instead of suppressing the "unused
643 * result" warning) you can use cxMapDetach().
644 *
645 * If this map is not storing pointers, this function behaves like
646 * cxMapRemove() and returns \c NULL.
647 *
648 * @param map the map
649 * @param key the key
650 * @return the stored pointer or \c NULL if either the key is not present
651 * in the map or the map is not storing pointers
652 * @see cxMapStorePointers()
653 * @see cxMapDetach()
654 */
655 __attribute__((__nonnull__, __warn_unused_result__))
656 static inline void *cxMapRemoveAndGet(
657 CxMap *map,
658 CxHashKey key
659 ) {
660 return map->cl->remove(map, key, !map->store_pointer);
661 }
662
663 /**
664 * Removes a key/value-pair from the map by using the key.
665 *
666 * This function can be used when the map is storing pointers,
667 * in order to retrieve the pointer from the map without invoking
668 * any destructor function. Sometimes you do not want the pointer
669 * to be returned - in that case (instead of suppressing the "unused
670 * result" warning) you can use cxMapDetach().
671 *
672 * If this map is not storing pointers, this function behaves like
673 * cxMapRemove() and returns \c NULL.
674 *
675 * @param map the map
676 * @param key the key
677 * @return the stored pointer or \c NULL if either the key is not present
678 * in the map or the map is not storing pointers
679 * @see cxMapStorePointers()
680 * @see cxMapDetach()
681 */
682 __attribute__((__nonnull__, __warn_unused_result__))
683 static inline void *cxMapRemoveAndGet(
684 CxMap *map,
685 cxstring key
686 ) {
687 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
688 }
689
690 /**
691 * Removes a key/value-pair from the map by using the key.
692 *
693 * This function can be used when the map is storing pointers,
694 * in order to retrieve the pointer from the map without invoking
695 * any destructor function. Sometimes you do not want the pointer
696 * to be returned - in that case (instead of suppressing the "unused
697 * result" warning) you can use cxMapDetach().
698 *
699 * If this map is not storing pointers, this function behaves like
700 * cxMapRemove() and returns \c NULL.
701 *
702 * @param map the map
703 * @param key the key
704 * @return the stored pointer or \c NULL if either the key is not present
705 * in the map or the map is not storing pointers
706 * @see cxMapStorePointers()
707 * @see cxMapDetach()
708 */
709 __attribute__((__nonnull__, __warn_unused_result__))
710 static inline void *cxMapRemoveAndGet(
711 CxMap *map,
712 cxmutstr key
713 ) {
714 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
715 }
716
717 /**
718 * Removes a key/value-pair from the map by using the key.
719 *
720 * This function can be used when the map is storing pointers,
721 * in order to retrieve the pointer from the map without invoking
722 * any destructor function. Sometimes you do not want the pointer
723 * to be returned - in that case (instead of suppressing the "unused
724 * result" warning) you can use cxMapDetach().
725 *
726 * If this map is not storing pointers, this function behaves like
727 * cxMapRemove() and returns \c NULL.
728 *
729 * @param map the map
730 * @param key the key
731 * @return the stored pointer or \c NULL if either the key is not present
732 * in the map or the map is not storing pointers
733 * @see cxMapStorePointers()
734 * @see cxMapDetach()
735 */
736 __attribute__((__nonnull__, __warn_unused_result__))
737 static inline void *cxMapRemoveAndGet(
738 CxMap *map,
739 char const *key
740 ) {
741 return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
742 } 484 }
743 485
744 #else // __cplusplus 486 #else // __cplusplus
745 487
746 /** 488 /**
747 * Puts a key/value-pair into the map. 489 * @copydoc cxMapPut()
748 * 490 */
749 * @param map the map 491 cx_attr_nonnull
750 * @param key the key
751 * @param value the value
752 * @return 0 on success, non-zero value on failure
753 */
754 __attribute__((__nonnull__))
755 static inline int cx_map_put( 492 static inline int cx_map_put(
756 CxMap *map, 493 CxMap *map,
757 CxHashKey key, 494 CxHashKey key,
758 void *value 495 void *value
759 ) { 496 ) {
760 return map->cl->put(map, key, value); 497 return map->cl->put(map, key, value);
761 } 498 }
762 499
763 /** 500 /**
764 * Puts a key/value-pair into the map. 501 * @copydoc cxMapPut()
765 * 502 */
766 * @param map the map 503 cx_attr_nonnull
767 * @param key the key
768 * @param value the value
769 * @return 0 on success, non-zero value on failure
770 */
771 __attribute__((__nonnull__))
772 static inline int cx_map_put_cxstr( 504 static inline int cx_map_put_cxstr(
773 CxMap *map, 505 CxMap *map,
774 cxstring key, 506 cxstring key,
775 void *value 507 void *value
776 ) { 508 ) {
777 return map->cl->put(map, cx_hash_key_cxstr(key), value); 509 return map->cl->put(map, cx_hash_key_cxstr(key), value);
778 } 510 }
779 511
780 /** 512 /**
781 * Puts a key/value-pair into the map. 513 * @copydoc cxMapPut()
782 * 514 */
783 * @param map the map 515 cx_attr_nonnull
784 * @param key the key
785 * @param value the value
786 * @return 0 on success, non-zero value on failure
787 */
788 __attribute__((__nonnull__))
789 static inline int cx_map_put_mustr( 516 static inline int cx_map_put_mustr(
790 CxMap *map, 517 CxMap *map,
791 cxmutstr key, 518 cxmutstr key,
792 void *value 519 void *value
793 ) { 520 ) {
794 return map->cl->put(map, cx_hash_key_cxstr(key), value); 521 return map->cl->put(map, cx_hash_key_cxstr(key), value);
795 } 522 }
796 523
797 /** 524 /**
525 * @copydoc cxMapPut()
526 */
527 cx_attr_nonnull
528 cx_attr_cstr_arg(2)
529 static inline int cx_map_put_str(
530 CxMap *map,
531 const char *key,
532 void *value
533 ) {
534 return map->cl->put(map, cx_hash_key_str(key), value);
535 }
536
537 /**
798 * Puts a key/value-pair into the map. 538 * Puts a key/value-pair into the map.
799 * 539 *
800 * @param map the map 540 * A possible existing value will be overwritten.
801 * @param key the key 541 *
802 * @param value the value 542 * If this map is storing pointers, the @p value pointer is written
803 * @return 0 on success, non-zero value on failure 543 * to the map. Otherwise, the memory is copied from @p value with
804 */ 544 * memcpy().
805 __attribute__((__nonnull__)) 545 *
806 static inline int cx_map_put_str( 546 * The @p key is always copied.
807 CxMap *map, 547 *
808 char const *key, 548 * @param map (@c CxMap*) the map
809 void *value 549 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
810 ) { 550 * @param value (@c void*) the value
811 return map->cl->put(map, cx_hash_key_str(key), value); 551 * @retval zero success
812 } 552 * @retval non-zero value on memory allocation failure
813
814 /**
815 * Puts a key/value-pair into the map.
816 *
817 * @param map the map
818 * @param key the key
819 * @param value the value
820 * @return 0 on success, non-zero value on failure
821 */ 553 */
822 #define cxMapPut(map, key, value) _Generic((key), \ 554 #define cxMapPut(map, key, value) _Generic((key), \
823 CxHashKey: cx_map_put, \ 555 CxHashKey: cx_map_put, \
824 cxstring: cx_map_put_cxstr, \ 556 cxstring: cx_map_put_cxstr, \
825 cxmutstr: cx_map_put_mustr, \ 557 cxmutstr: cx_map_put_mustr, \
826 char*: cx_map_put_str, \ 558 char*: cx_map_put_str, \
827 char const*: cx_map_put_str) \ 559 const char*: cx_map_put_str) \
828 (map, key, value) 560 (map, key, value)
829 561
830 /** 562 /**
563 * @copydoc cxMapGet()
564 */
565 cx_attr_nonnull
566 cx_attr_nodiscard
567 static inline void *cx_map_get(
568 const CxMap *map,
569 CxHashKey key
570 ) {
571 return map->cl->get(map, key);
572 }
573
574 /**
575 * @copydoc cxMapGet()
576 */
577 cx_attr_nonnull
578 cx_attr_nodiscard
579 static inline void *cx_map_get_cxstr(
580 const CxMap *map,
581 cxstring key
582 ) {
583 return map->cl->get(map, cx_hash_key_cxstr(key));
584 }
585
586 /**
587 * @copydoc cxMapGet()
588 */
589 cx_attr_nonnull
590 cx_attr_nodiscard
591 static inline void *cx_map_get_mustr(
592 const CxMap *map,
593 cxmutstr key
594 ) {
595 return map->cl->get(map, cx_hash_key_cxstr(key));
596 }
597
598 /**
599 * @copydoc cxMapGet()
600 */
601 cx_attr_nonnull
602 cx_attr_nodiscard
603 cx_attr_cstr_arg(2)
604 static inline void *cx_map_get_str(
605 const CxMap *map,
606 const char *key
607 ) {
608 return map->cl->get(map, cx_hash_key_str(key));
609 }
610
611 /**
831 * Retrieves a value by using a key. 612 * Retrieves a value by using a key.
832 * 613 *
833 * @param map the map 614 * If this map is storing pointers, the stored pointer is returned.
834 * @param key the key 615 * Otherwise, a pointer to the element within the map's memory
835 * @return the value 616 * is returned (which is valid as long as the element stays in the map).
836 */ 617 *
837 __attribute__((__nonnull__, __warn_unused_result__)) 618 * @param map (@c CxMap*) the map
838 static inline void *cx_map_get( 619 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
839 CxMap const *map, 620 * @return (@c void*) the value
840 CxHashKey key
841 ) {
842 return map->cl->get(map, key);
843 }
844
845 /**
846 * Retrieves a value by using a key.
847 *
848 * @param map the map
849 * @param key the key
850 * @return the value
851 */
852 __attribute__((__nonnull__, __warn_unused_result__))
853 static inline void *cx_map_get_cxstr(
854 CxMap const *map,
855 cxstring key
856 ) {
857 return map->cl->get(map, cx_hash_key_cxstr(key));
858 }
859
860 /**
861 * Retrieves a value by using a key.
862 *
863 * @param map the map
864 * @param key the key
865 * @return the value
866 */
867 __attribute__((__nonnull__, __warn_unused_result__))
868 static inline void *cx_map_get_mustr(
869 CxMap const *map,
870 cxmutstr key
871 ) {
872 return map->cl->get(map, cx_hash_key_cxstr(key));
873 }
874
875 /**
876 * Retrieves a value by using a key.
877 *
878 * @param map the map
879 * @param key the key
880 * @return the value
881 */
882 __attribute__((__nonnull__, __warn_unused_result__))
883 static inline void *cx_map_get_str(
884 CxMap const *map,
885 char const *key
886 ) {
887 return map->cl->get(map, cx_hash_key_str(key));
888 }
889
890 /**
891 * Retrieves a value by using a key.
892 *
893 * @param map the map
894 * @param key the key
895 * @return the value
896 */ 621 */
897 #define cxMapGet(map, key) _Generic((key), \ 622 #define cxMapGet(map, key) _Generic((key), \
898 CxHashKey: cx_map_get, \ 623 CxHashKey: cx_map_get, \
899 cxstring: cx_map_get_cxstr, \ 624 cxstring: cx_map_get_cxstr, \
900 cxmutstr: cx_map_get_mustr, \ 625 cxmutstr: cx_map_get_mustr, \
901 char*: cx_map_get_str, \ 626 char*: cx_map_get_str, \
902 char const*: cx_map_get_str) \ 627 const char*: cx_map_get_str) \
903 (map, key) 628 (map, key)
904 629
905 /** 630 /**
631 * @copydoc cxMapRemove()
632 */
633 cx_attr_nonnull
634 static inline int cx_map_remove(
635 CxMap *map,
636 CxHashKey key
637 ) {
638 return map->cl->remove(map, key, NULL);
639 }
640
641 /**
642 * @copydoc cxMapRemove()
643 */
644 cx_attr_nonnull
645 static inline int cx_map_remove_cxstr(
646 CxMap *map,
647 cxstring key
648 ) {
649 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
650 }
651
652 /**
653 * @copydoc cxMapRemove()
654 */
655 cx_attr_nonnull
656 static inline int cx_map_remove_mustr(
657 CxMap *map,
658 cxmutstr key
659 ) {
660 return map->cl->remove(map, cx_hash_key_cxstr(key), NULL);
661 }
662
663 /**
664 * @copydoc cxMapRemove()
665 */
666 cx_attr_nonnull
667 cx_attr_cstr_arg(2)
668 static inline int cx_map_remove_str(
669 CxMap *map,
670 const char *key
671 ) {
672 return map->cl->remove(map, cx_hash_key_str(key), NULL);
673 }
674
675 /**
906 * Removes a key/value-pair from the map by using the key. 676 * Removes a key/value-pair from the map by using the key.
907 * 677 *
908 * @param map the map 678 * Always invokes the destructors functions, if any, on the removed element.
909 * @param key the key 679 *
910 */ 680 * @param map (@c CxMap*) the map
911 __attribute__((__nonnull__)) 681 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
912 static inline void cx_map_remove( 682 * @retval zero success
913 CxMap *map, 683 * @retval non-zero the key was not found
914 CxHashKey key 684 *
915 ) {
916 (void) map->cl->remove(map, key, true);
917 }
918
919 /**
920 * Removes a key/value-pair from the map by using the key.
921 *
922 * @param map the map
923 * @param key the key
924 */
925 __attribute__((__nonnull__))
926 static inline void cx_map_remove_cxstr(
927 CxMap *map,
928 cxstring key
929 ) {
930 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
931 }
932
933 /**
934 * Removes a key/value-pair from the map by using the key.
935 *
936 * @param map the map
937 * @param key the key
938 */
939 __attribute__((__nonnull__))
940 static inline void cx_map_remove_mustr(
941 CxMap *map,
942 cxmutstr key
943 ) {
944 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
945 }
946
947 /**
948 * Removes a key/value-pair from the map by using the key.
949 *
950 * @param map the map
951 * @param key the key
952 */
953 __attribute__((__nonnull__))
954 static inline void cx_map_remove_str(
955 CxMap *map,
956 char const *key
957 ) {
958 (void) map->cl->remove(map, cx_hash_key_str(key), true);
959 }
960
961 /**
962 * Removes a key/value-pair from the map by using the key.
963 *
964 * Always invokes the destructor function, if any, on the removed element.
965 * If this map is storing pointers and you just want to retrieve the pointer
966 * without invoking the destructor, use cxMapRemoveAndGet().
967 * If you just want to detach the element from the map without invoking the
968 * destructor or returning the element, use cxMapDetach().
969 *
970 * @param map the map
971 * @param key the key
972 * @see cxMapRemoveAndGet() 685 * @see cxMapRemoveAndGet()
973 * @see cxMapDetach()
974 */ 686 */
975 #define cxMapRemove(map, key) _Generic((key), \ 687 #define cxMapRemove(map, key) _Generic((key), \
976 CxHashKey: cx_map_remove, \ 688 CxHashKey: cx_map_remove, \
977 cxstring: cx_map_remove_cxstr, \ 689 cxstring: cx_map_remove_cxstr, \
978 cxmutstr: cx_map_remove_mustr, \ 690 cxmutstr: cx_map_remove_mustr, \
979 char*: cx_map_remove_str, \ 691 char*: cx_map_remove_str, \
980 char const*: cx_map_remove_str) \ 692 const char*: cx_map_remove_str) \
981 (map, key) 693 (map, key)
982 694
983 /** 695 /**
984 * Detaches a key/value-pair from the map by using the key 696 * @copydoc cxMapRemoveAndGet()
985 * without invoking the destructor. 697 */
986 * 698 cx_attr_nonnull
987 * @param map the map 699 cx_attr_access_w(3)
988 * @param key the key 700 static inline int cx_map_remove_and_get(
989 */ 701 CxMap *map,
990 __attribute__((__nonnull__)) 702 CxHashKey key,
991 static inline void cx_map_detach( 703 void *targetbuf
992 CxMap *map, 704 ) {
993 CxHashKey key 705 return map->cl->remove(map, key, targetbuf);
994 ) { 706 }
995 (void) map->cl->remove(map, key, false); 707
996 } 708 /**
997 709 * @copydoc cxMapRemoveAndGet()
998 /** 710 */
999 * Detaches a key/value-pair from the map by using the key 711 cx_attr_nonnull
1000 * without invoking the destructor. 712 cx_attr_access_w(3)
1001 * 713 static inline int cx_map_remove_and_get_cxstr(
1002 * @param map the map 714 CxMap *map,
1003 * @param key the key 715 cxstring key,
1004 */ 716 void *targetbuf
1005 __attribute__((__nonnull__)) 717 ) {
1006 static inline void cx_map_detach_cxstr( 718 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
1007 CxMap *map, 719 }
1008 cxstring key 720
1009 ) { 721 /**
1010 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 722 * @copydoc cxMapRemoveAndGet()
1011 } 723 */
1012 724 cx_attr_nonnull
1013 /** 725 cx_attr_access_w(3)
1014 * Detaches a key/value-pair from the map by using the key 726 static inline int cx_map_remove_and_get_mustr(
1015 * without invoking the destructor. 727 CxMap *map,
1016 * 728 cxmutstr key,
1017 * @param map the map 729 void *targetbuf
1018 * @param key the key 730 ) {
1019 */ 731 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
1020 __attribute__((__nonnull__)) 732 }
1021 static inline void cx_map_detach_mustr( 733
1022 CxMap *map, 734 /**
1023 cxmutstr key 735 * @copydoc cxMapRemoveAndGet()
1024 ) { 736 */
1025 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 737 cx_attr_nonnull
1026 } 738 cx_attr_access_w(3)
1027 739 cx_attr_cstr_arg(2)
1028 /** 740 static inline int cx_map_remove_and_get_str(
1029 * Detaches a key/value-pair from the map by using the key 741 CxMap *map,
1030 * without invoking the destructor. 742 const char *key,
1031 * 743 void *targetbuf
1032 * @param map the map 744 ) {
1033 * @param key the key 745 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
1034 */ 746 }
1035 __attribute__((__nonnull__)) 747
1036 static inline void cx_map_detach_str( 748 /**
1037 CxMap *map, 749 * Removes a key/value-pair from the map by using the key.
1038 char const *key 750 *
1039 ) { 751 * This function will copy the contents of the removed element
1040 (void) map->cl->remove(map, cx_hash_key_str(key), false); 752 * to the target buffer must be guaranteed to be large enough
1041 } 753 * to hold the element (the map's element size).
1042 754 * The destructor functions, if any, will @em not be called.
1043 /** 755 *
1044 * Detaches a key/value-pair from the map by using the key 756 * If this map is storing pointers, the element is the pointer itself
1045 * without invoking the destructor. 757 * and not the object it points to.
1046 * 758 *
1047 * In general, you should only use this function if the map does not own 759 * @param map (@c CxMap*) the map
1048 * the data and there is a valid reference to the data somewhere else 760 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
1049 * in the program. In all other cases it is preferable to use 761 * @param targetbuf (@c void*) the buffer where the element shall be copied to
1050 * cxMapRemove() or cxMapRemoveAndGet(). 762 * @retval zero success
1051 * 763 * @retval non-zero the key was not found
1052 * @param map the map 764 *
1053 * @param key the key 765 * @see cxMapStorePointers()
1054 * @see cxMapRemove() 766 * @see cxMapRemove()
1055 * @see cxMapRemoveAndGet() 767 */
1056 */ 768 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \
1057 #define cxMapDetach(map, key) _Generic((key), \
1058 CxHashKey: cx_map_detach, \
1059 cxstring: cx_map_detach_cxstr, \
1060 cxmutstr: cx_map_detach_mustr, \
1061 char*: cx_map_detach_str, \
1062 char const*: cx_map_detach_str) \
1063 (map, key)
1064
1065 /**
1066 * Removes a key/value-pair from the map by using the key.
1067 *
1068 * @param map the map
1069 * @param key the key
1070 * @return the stored pointer or \c NULL if either the key is not present
1071 * in the map or the map is not storing pointers
1072 */
1073 __attribute__((__nonnull__, __warn_unused_result__))
1074 static inline void *cx_map_remove_and_get(
1075 CxMap *map,
1076 CxHashKey key
1077 ) {
1078 return map->cl->remove(map, key, !map->collection.store_pointer);
1079 }
1080
1081 /**
1082 * Removes a key/value-pair from the map by using the key.
1083 *
1084 * @param map the map
1085 * @param key the key
1086 * @return the stored pointer or \c NULL if either the key is not present
1087 * in the map or the map is not storing pointers
1088 */
1089 __attribute__((__nonnull__, __warn_unused_result__))
1090 static inline void *cx_map_remove_and_get_cxstr(
1091 CxMap *map,
1092 cxstring key
1093 ) {
1094 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
1095 }
1096
1097 /**
1098 * Removes a key/value-pair from the map by using the key.
1099 *
1100 * @param map the map
1101 * @param key the key
1102 * @return the stored pointer or \c NULL if either the key is not present
1103 * in the map or the map is not storing pointers
1104 */
1105 __attribute__((__nonnull__, __warn_unused_result__))
1106 static inline void *cx_map_remove_and_get_mustr(
1107 CxMap *map,
1108 cxmutstr key
1109 ) {
1110 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
1111 }
1112
1113 /**
1114 * Removes a key/value-pair from the map by using the key.
1115 *
1116 * @param map the map
1117 * @param key the key
1118 * @return the stored pointer or \c NULL if either the key is not present
1119 * in the map or the map is not storing pointers
1120 */
1121 __attribute__((__nonnull__, __warn_unused_result__))
1122 static inline void *cx_map_remove_and_get_str(
1123 CxMap *map,
1124 char const *key
1125 ) {
1126 return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
1127 }
1128
1129 /**
1130 * Removes a key/value-pair from the map by using the key.
1131 *
1132 * This function can be used when the map is storing pointers,
1133 * in order to retrieve the pointer from the map without invoking
1134 * any destructor function. Sometimes you do not want the pointer
1135 * to be returned - in that case (instead of suppressing the "unused
1136 * result" warning) you can use cxMapDetach().
1137 *
1138 * If this map is not storing pointers, this function behaves like
1139 * cxMapRemove() and returns \c NULL.
1140 *
1141 * @param map the map
1142 * @param key the key
1143 * @return the stored pointer or \c NULL if either the key is not present
1144 * in the map or the map is not storing pointers
1145 * @see cxMapStorePointers()
1146 * @see cxMapDetach()
1147 */
1148 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1149 CxHashKey: cx_map_remove_and_get, \ 769 CxHashKey: cx_map_remove_and_get, \
1150 cxstring: cx_map_remove_and_get_cxstr, \ 770 cxstring: cx_map_remove_and_get_cxstr, \
1151 cxmutstr: cx_map_remove_and_get_mustr, \ 771 cxmutstr: cx_map_remove_and_get_mustr, \
1152 char*: cx_map_remove_and_get_str, \ 772 char*: cx_map_remove_and_get_str, \
1153 char const*: cx_map_remove_and_get_str) \ 773 const char*: cx_map_remove_and_get_str) \
1154 (map, key) 774 (map, key, targetbuf)
1155 775
1156 #endif // __cplusplus 776 #endif // __cplusplus
1157 777
1158 #endif // UCX_MAP_H 778 #endif // UCX_MAP_H

mercurial