ucx/cx/map.h

changeset 101
7b3a3130be44
parent 77
5de33c2d94c6
equal deleted inserted replaced
100:d2bd73d28ff1 101:7b3a3130be44
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 const CxMap *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__))
134 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type); 135 CxIterator (*iterator)(const CxMap *map, enum cx_map_iterator_type type);
135 }; 136 };
136 137
137 /** 138 /**
138 * A map entry. 139 * A map entry.
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(const CxMap *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(const CxMap *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
249 cx_attr_nodiscard
247 static inline CxIterator cxMapIteratorValues(const CxMap *map) { 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
266 cx_attr_nodiscard
263 static inline CxIterator cxMapIteratorKeys(const CxMap *map) { 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
285 cx_attr_nodiscard
281 static inline CxIterator cxMapIterator(const CxMap *map) { 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 const char *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 const CxMap *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 const CxMap *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 const CxMap *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 const CxMap *map, 406 const CxMap *map,
455 const char *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.
530 * If this map is storing pointers and you just want to retrieve the pointer
531 * without invoking the destructor, use cxMapRemoveAndGet().
532 * If you just want to detach the element from the map without invoking the
533 * destructor or returning the element, use cxMapDetach().
534 *
535 * @param map the map
536 * @param key the key
537 * @see cxMapRemoveAndGet()
538 * @see cxMapDetach()
539 */
540 __attribute__((__nonnull__))
541 static inline void cxMapRemove(
542 CxMap *map, 439 CxMap *map,
543 const char *key 440 const char *key
544 ) { 441 ) {
545 (void) map->cl->remove(map, cx_hash_key_str(key), true); 442 return map->cl->remove(map, cx_hash_key_str(key), nullptr);
546 } 443 }
547 444
548 /** 445 cx_attr_nonnull
549 * Detaches a key/value-pair from the map by using the key 446 cx_attr_access_w(3)
550 * without invoking the destructor. 447 static inline int cxMapRemoveAndGet(
551 * 448 CxMap *map,
552 * In general, you should only use this function if the map does not own 449 CxHashKey key,
553 * the data and there is a valid reference to the data somewhere else 450 void *targetbuf
554 * in the program. In all other cases it is preferable to use 451 ) {
555 * cxMapRemove() or cxMapRemoveAndGet(). 452 return map->cl->remove(map, key, targetbuf);
556 * 453 }
557 * @param map the map 454
558 * @param key the key 455 cx_attr_nonnull
559 * @see cxMapRemove() 456 cx_attr_access_w(3)
560 * @see cxMapRemoveAndGet() 457 static inline int cxMapRemoveAndGet(
561 */ 458 CxMap *map,
562 __attribute__((__nonnull__)) 459 cxstring key,
563 static inline void cxMapDetach( 460 void *targetbuf
564 CxMap *map, 461 ) {
565 CxHashKey const &key 462 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
566 ) { 463 }
567 (void) map->cl->remove(map, key, false); 464
568 } 465 cx_attr_nonnull
569 466 cx_attr_access_w(3)
570 /** 467 static inline int cxMapRemoveAndGet(
571 * Detaches a key/value-pair from the map by using the key 468 CxMap *map,
572 * without invoking the destructor. 469 cxmutstr key,
573 * 470 void *targetbuf
574 * In general, you should only use this function if the map does not own 471 ) {
575 * the data and there is a valid reference to the data somewhere else 472 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
576 * in the program. In all other cases it is preferable to use 473 }
577 * cxMapRemove() or cxMapRemoveAndGet(). 474
578 * 475 cx_attr_nonnull
579 * @param map the map 476 cx_attr_access_w(3)
580 * @param key the key 477 cx_attr_cstr_arg(2)
581 * @see cxMapRemove() 478 static inline int cxMapRemoveAndGet(
582 * @see cxMapRemoveAndGet() 479 CxMap *map,
583 */ 480 const char *key,
584 __attribute__((__nonnull__)) 481 void *targetbuf
585 static inline void cxMapDetach( 482 ) {
586 CxMap *map, 483 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
587 cxstring const &key 484 }
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 const char *key
632 ) {
633 (void) map->cl->remove(map, cx_hash_key_str(key), false);
634 }
635
636
637 485
638 #else // __cplusplus 486 #else // __cplusplus
639 487
640 /** 488 /**
641 * Puts a key/value-pair into the map. 489 * @copydoc cxMapPut()
642 * 490 */
643 * @param map the map 491 cx_attr_nonnull
644 * @param key the key
645 * @param value the value
646 * @return 0 on success, non-zero value on failure
647 */
648 __attribute__((__nonnull__))
649 static inline int cx_map_put( 492 static inline int cx_map_put(
650 CxMap *map, 493 CxMap *map,
651 CxHashKey key, 494 CxHashKey key,
652 void *value 495 void *value
653 ) { 496 ) {
654 return map->cl->put(map, key, value); 497 return map->cl->put(map, key, value);
655 } 498 }
656 499
657 /** 500 /**
658 * Puts a key/value-pair into the map. 501 * @copydoc cxMapPut()
659 * 502 */
660 * @param map the map 503 cx_attr_nonnull
661 * @param key the key
662 * @param value the value
663 * @return 0 on success, non-zero value on failure
664 */
665 __attribute__((__nonnull__))
666 static inline int cx_map_put_cxstr( 504 static inline int cx_map_put_cxstr(
667 CxMap *map, 505 CxMap *map,
668 cxstring key, 506 cxstring key,
669 void *value 507 void *value
670 ) { 508 ) {
671 return map->cl->put(map, cx_hash_key_cxstr(key), value); 509 return map->cl->put(map, cx_hash_key_cxstr(key), value);
672 } 510 }
673 511
674 /** 512 /**
675 * Puts a key/value-pair into the map. 513 * @copydoc cxMapPut()
676 * 514 */
677 * @param map the map 515 cx_attr_nonnull
678 * @param key the key
679 * @param value the value
680 * @return 0 on success, non-zero value on failure
681 */
682 __attribute__((__nonnull__))
683 static inline int cx_map_put_mustr( 516 static inline int cx_map_put_mustr(
684 CxMap *map, 517 CxMap *map,
685 cxmutstr key, 518 cxmutstr key,
686 void *value 519 void *value
687 ) { 520 ) {
688 return map->cl->put(map, cx_hash_key_cxstr(key), value); 521 return map->cl->put(map, cx_hash_key_cxstr(key), value);
689 } 522 }
690 523
691 /** 524 /**
692 * Puts a key/value-pair into the map. 525 * @copydoc cxMapPut()
693 * 526 */
694 * @param map the map 527 cx_attr_nonnull
695 * @param key the key 528 cx_attr_cstr_arg(2)
696 * @param value the value
697 * @return 0 on success, non-zero value on failure
698 */
699 __attribute__((__nonnull__))
700 static inline int cx_map_put_str( 529 static inline int cx_map_put_str(
701 CxMap *map, 530 CxMap *map,
702 const char *key, 531 const char *key,
703 void *value 532 void *value
704 ) { 533 ) {
706 } 535 }
707 536
708 /** 537 /**
709 * Puts a key/value-pair into the map. 538 * Puts a key/value-pair into the map.
710 * 539 *
711 * @param map the map 540 * A possible existing value will be overwritten.
712 * @param key the key 541 *
713 * @param value the value 542 * If this map is storing pointers, the @p value pointer is written
714 * @return 0 on success, non-zero value on failure 543 * to the map. Otherwise, the memory is copied from @p value with
544 * memcpy().
545 *
546 * The @p key is always copied.
547 *
548 * @param map (@c CxMap*) the map
549 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
550 * @param value (@c void*) the value
551 * @retval zero success
552 * @retval non-zero value on memory allocation failure
715 */ 553 */
716 #define cxMapPut(map, key, value) _Generic((key), \ 554 #define cxMapPut(map, key, value) _Generic((key), \
717 CxHashKey: cx_map_put, \ 555 CxHashKey: cx_map_put, \
718 cxstring: cx_map_put_cxstr, \ 556 cxstring: cx_map_put_cxstr, \
719 cxmutstr: cx_map_put_mustr, \ 557 cxmutstr: cx_map_put_mustr, \
720 char*: cx_map_put_str, \ 558 char*: cx_map_put_str, \
721 const char*: cx_map_put_str) \ 559 const char*: cx_map_put_str) \
722 (map, key, value) 560 (map, key, value)
723 561
724 /** 562 /**
725 * Retrieves a value by using a key. 563 * @copydoc cxMapGet()
726 * 564 */
727 * @param map the map 565 cx_attr_nonnull
728 * @param key the key 566 cx_attr_nodiscard
729 * @return the value
730 */
731 __attribute__((__nonnull__, __warn_unused_result__))
732 static inline void *cx_map_get( 567 static inline void *cx_map_get(
733 const CxMap *map, 568 const CxMap *map,
734 CxHashKey key 569 CxHashKey key
735 ) { 570 ) {
736 return map->cl->get(map, key); 571 return map->cl->get(map, key);
737 } 572 }
738 573
739 /** 574 /**
740 * Retrieves a value by using a key. 575 * @copydoc cxMapGet()
741 * 576 */
742 * @param map the map 577 cx_attr_nonnull
743 * @param key the key 578 cx_attr_nodiscard
744 * @return the value
745 */
746 __attribute__((__nonnull__, __warn_unused_result__))
747 static inline void *cx_map_get_cxstr( 579 static inline void *cx_map_get_cxstr(
748 const CxMap *map, 580 const CxMap *map,
749 cxstring key 581 cxstring key
750 ) { 582 ) {
751 return map->cl->get(map, cx_hash_key_cxstr(key)); 583 return map->cl->get(map, cx_hash_key_cxstr(key));
752 } 584 }
753 585
754 /** 586 /**
755 * Retrieves a value by using a key. 587 * @copydoc cxMapGet()
756 * 588 */
757 * @param map the map 589 cx_attr_nonnull
758 * @param key the key 590 cx_attr_nodiscard
759 * @return the value
760 */
761 __attribute__((__nonnull__, __warn_unused_result__))
762 static inline void *cx_map_get_mustr( 591 static inline void *cx_map_get_mustr(
763 const CxMap *map, 592 const CxMap *map,
764 cxmutstr key 593 cxmutstr key
765 ) { 594 ) {
766 return map->cl->get(map, cx_hash_key_cxstr(key)); 595 return map->cl->get(map, cx_hash_key_cxstr(key));
767 } 596 }
768 597
769 /** 598 /**
770 * Retrieves a value by using a key. 599 * @copydoc cxMapGet()
771 * 600 */
772 * @param map the map 601 cx_attr_nonnull
773 * @param key the key 602 cx_attr_nodiscard
774 * @return the value 603 cx_attr_cstr_arg(2)
775 */
776 __attribute__((__nonnull__, __warn_unused_result__))
777 static inline void *cx_map_get_str( 604 static inline void *cx_map_get_str(
778 const CxMap *map, 605 const CxMap *map,
779 const char *key 606 const char *key
780 ) { 607 ) {
781 return map->cl->get(map, cx_hash_key_str(key)); 608 return map->cl->get(map, cx_hash_key_str(key));
782 } 609 }
783 610
784 /** 611 /**
785 * Retrieves a value by using a key. 612 * Retrieves a value by using a key.
786 * 613 *
787 * @param map the map 614 * If this map is storing pointers, the stored pointer is returned.
788 * @param key the key 615 * Otherwise, a pointer to the element within the map's memory
789 * @return the value 616 * is returned (which is valid as long as the element stays in the map).
617 *
618 * @param map (@c CxMap*) the map
619 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
620 * @return (@c void*) the value
790 */ 621 */
791 #define cxMapGet(map, key) _Generic((key), \ 622 #define cxMapGet(map, key) _Generic((key), \
792 CxHashKey: cx_map_get, \ 623 CxHashKey: cx_map_get, \
793 cxstring: cx_map_get_cxstr, \ 624 cxstring: cx_map_get_cxstr, \
794 cxmutstr: cx_map_get_mustr, \ 625 cxmutstr: cx_map_get_mustr, \
795 char*: cx_map_get_str, \ 626 char*: cx_map_get_str, \
796 const char*: cx_map_get_str) \ 627 const char*: cx_map_get_str) \
797 (map, key) 628 (map, key)
798 629
799 /** 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 /**
800 * 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.
801 * 677 *
802 * @param map the map 678 * Always invokes the destructors functions, if any, on the removed element.
803 * @param key the key 679 *
804 */ 680 * @param map (@c CxMap*) the map
805 __attribute__((__nonnull__)) 681 * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key
806 static inline void cx_map_remove( 682 * @retval zero success
807 CxMap *map, 683 * @retval non-zero the key was not found
808 CxHashKey key 684 *
809 ) {
810 (void) map->cl->remove(map, key, true);
811 }
812
813 /**
814 * Removes a key/value-pair from the map by using the key.
815 *
816 * @param map the map
817 * @param key the key
818 */
819 __attribute__((__nonnull__))
820 static inline void cx_map_remove_cxstr(
821 CxMap *map,
822 cxstring key
823 ) {
824 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
825 }
826
827 /**
828 * Removes a key/value-pair from the map by using the key.
829 *
830 * @param map the map
831 * @param key the key
832 */
833 __attribute__((__nonnull__))
834 static inline void cx_map_remove_mustr(
835 CxMap *map,
836 cxmutstr key
837 ) {
838 (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
839 }
840
841 /**
842 * Removes a key/value-pair from the map by using the key.
843 *
844 * @param map the map
845 * @param key the key
846 */
847 __attribute__((__nonnull__))
848 static inline void cx_map_remove_str(
849 CxMap *map,
850 const char *key
851 ) {
852 (void) map->cl->remove(map, cx_hash_key_str(key), true);
853 }
854
855 /**
856 * Removes a key/value-pair from the map by using the key.
857 *
858 * Always invokes the destructor function, if any, on the removed element.
859 * If this map is storing pointers and you just want to retrieve the pointer
860 * without invoking the destructor, use cxMapRemoveAndGet().
861 * If you just want to detach the element from the map without invoking the
862 * destructor or returning the element, use cxMapDetach().
863 *
864 * @param map the map
865 * @param key the key
866 * @see cxMapRemoveAndGet() 685 * @see cxMapRemoveAndGet()
867 * @see cxMapDetach()
868 */ 686 */
869 #define cxMapRemove(map, key) _Generic((key), \ 687 #define cxMapRemove(map, key) _Generic((key), \
870 CxHashKey: cx_map_remove, \ 688 CxHashKey: cx_map_remove, \
871 cxstring: cx_map_remove_cxstr, \ 689 cxstring: cx_map_remove_cxstr, \
872 cxmutstr: cx_map_remove_mustr, \ 690 cxmutstr: cx_map_remove_mustr, \
873 char*: cx_map_remove_str, \ 691 char*: cx_map_remove_str, \
874 const char*: cx_map_remove_str) \ 692 const char*: cx_map_remove_str) \
875 (map, key) 693 (map, key)
876 694
877 /** 695 /**
878 * Detaches a key/value-pair from the map by using the key 696 * @copydoc cxMapRemoveAndGet()
879 * without invoking the destructor. 697 */
880 * 698 cx_attr_nonnull
881 * @param map the map 699 cx_attr_access_w(3)
882 * @param key the key 700 static inline int cx_map_remove_and_get(
883 */ 701 CxMap *map,
884 __attribute__((__nonnull__)) 702 CxHashKey key,
885 static inline void cx_map_detach( 703 void *targetbuf
886 CxMap *map, 704 ) {
887 CxHashKey key 705 return map->cl->remove(map, key, targetbuf);
888 ) { 706 }
889 (void) map->cl->remove(map, key, false); 707
890 } 708 /**
891 709 * @copydoc cxMapRemoveAndGet()
892 /** 710 */
893 * Detaches a key/value-pair from the map by using the key 711 cx_attr_nonnull
894 * without invoking the destructor. 712 cx_attr_access_w(3)
895 * 713 static inline int cx_map_remove_and_get_cxstr(
896 * @param map the map 714 CxMap *map,
897 * @param key the key 715 cxstring key,
898 */ 716 void *targetbuf
899 __attribute__((__nonnull__)) 717 ) {
900 static inline void cx_map_detach_cxstr( 718 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
901 CxMap *map, 719 }
902 cxstring key 720
903 ) { 721 /**
904 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 722 * @copydoc cxMapRemoveAndGet()
905 } 723 */
906 724 cx_attr_nonnull
907 /** 725 cx_attr_access_w(3)
908 * Detaches a key/value-pair from the map by using the key 726 static inline int cx_map_remove_and_get_mustr(
909 * without invoking the destructor. 727 CxMap *map,
910 * 728 cxmutstr key,
911 * @param map the map 729 void *targetbuf
912 * @param key the key 730 ) {
913 */ 731 return map->cl->remove(map, cx_hash_key_cxstr(key), targetbuf);
914 __attribute__((__nonnull__)) 732 }
915 static inline void cx_map_detach_mustr( 733
916 CxMap *map, 734 /**
917 cxmutstr key 735 * @copydoc cxMapRemoveAndGet()
918 ) { 736 */
919 (void) map->cl->remove(map, cx_hash_key_cxstr(key), false); 737 cx_attr_nonnull
920 } 738 cx_attr_access_w(3)
921 739 cx_attr_cstr_arg(2)
922 /** 740 static inline int cx_map_remove_and_get_str(
923 * Detaches a key/value-pair from the map by using the key 741 CxMap *map,
924 * without invoking the destructor. 742 const char *key,
925 * 743 void *targetbuf
926 * @param map the map 744 ) {
927 * @param key the key 745 return map->cl->remove(map, cx_hash_key_str(key), targetbuf);
928 */ 746 }
929 __attribute__((__nonnull__)) 747
930 static inline void cx_map_detach_str( 748 /**
931 CxMap *map, 749 * Removes a key/value-pair from the map by using the key.
932 const char *key 750 *
933 ) { 751 * This function will copy the contents of the removed element
934 (void) map->cl->remove(map, cx_hash_key_str(key), false); 752 * to the target buffer must be guaranteed to be large enough
935 } 753 * to hold the element (the map's element size).
936 754 * The destructor functions, if any, will @em not be called.
937 /** 755 *
938 * 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
939 * without invoking the destructor. 757 * and not the object it points to.
940 * 758 *
941 * In general, you should only use this function if the map does not own 759 * @param map (@c CxMap*) the map
942 * 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
943 * 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
944 * cxMapRemove() or cxMapRemoveAndGet(). 762 * @retval zero success
945 * 763 * @retval non-zero the key was not found
946 * @param map the map 764 *
947 * @param key the key 765 * @see cxMapStorePointers()
948 * @see cxMapRemove() 766 * @see cxMapRemove()
949 * @see cxMapRemoveAndGet() 767 */
950 */ 768 #define cxMapRemoveAndGet(map, key, targetbuf) _Generic((key), \
951 #define cxMapDetach(map, key) _Generic((key), \
952 CxHashKey: cx_map_detach, \
953 cxstring: cx_map_detach_cxstr, \
954 cxmutstr: cx_map_detach_mustr, \
955 char*: cx_map_detach_str, \
956 const char*: cx_map_detach_str) \
957 (map, key)
958
959 /**
960 * Removes a key/value-pair from the map by using the key.
961 *
962 * @param map the map
963 * @param key the key
964 * @return the stored pointer or \c NULL if either the key is not present
965 * in the map or the map is not storing pointers
966 */
967 __attribute__((__nonnull__, __warn_unused_result__))
968 static inline void *cx_map_remove_and_get(
969 CxMap *map,
970 CxHashKey key
971 ) {
972 return map->cl->remove(map, key, !map->collection.store_pointer);
973 }
974
975 /**
976 * Removes a key/value-pair from the map by using the key.
977 *
978 * @param map the map
979 * @param key the key
980 * @return the stored pointer or \c NULL if either the key is not present
981 * in the map or the map is not storing pointers
982 */
983 __attribute__((__nonnull__, __warn_unused_result__))
984 static inline void *cx_map_remove_and_get_cxstr(
985 CxMap *map,
986 cxstring key
987 ) {
988 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
989 }
990
991 /**
992 * Removes a key/value-pair from the map by using the key.
993 *
994 * @param map the map
995 * @param key the key
996 * @return the stored pointer or \c NULL if either the key is not present
997 * in the map or the map is not storing pointers
998 */
999 __attribute__((__nonnull__, __warn_unused_result__))
1000 static inline void *cx_map_remove_and_get_mustr(
1001 CxMap *map,
1002 cxmutstr key
1003 ) {
1004 return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
1005 }
1006
1007 /**
1008 * Removes a key/value-pair from the map by using the key.
1009 *
1010 * @param map the map
1011 * @param key the key
1012 * @return the stored pointer or \c NULL if either the key is not present
1013 * in the map or the map is not storing pointers
1014 */
1015 __attribute__((__nonnull__, __warn_unused_result__))
1016 static inline void *cx_map_remove_and_get_str(
1017 CxMap *map,
1018 const char *key
1019 ) {
1020 return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
1021 }
1022
1023 /**
1024 * Removes a key/value-pair from the map by using the key.
1025 *
1026 * This function can be used when the map is storing pointers,
1027 * in order to retrieve the pointer from the map without invoking
1028 * any destructor function. Sometimes you do not want the pointer
1029 * to be returned - in that case (instead of suppressing the "unused
1030 * result" warning) you can use cxMapDetach().
1031 *
1032 * If this map is not storing pointers, this function behaves like
1033 * cxMapRemove() and returns \c NULL.
1034 *
1035 * @param map the map
1036 * @param key the key
1037 * @return the stored pointer or \c NULL if either the key is not present
1038 * in the map or the map is not storing pointers
1039 * @see cxMapStorePointers()
1040 * @see cxMapDetach()
1041 */
1042 #define cxMapRemoveAndGet(map, key) _Generic((key), \
1043 CxHashKey: cx_map_remove_and_get, \ 769 CxHashKey: cx_map_remove_and_get, \
1044 cxstring: cx_map_remove_and_get_cxstr, \ 770 cxstring: cx_map_remove_and_get_cxstr, \
1045 cxmutstr: cx_map_remove_and_get_mustr, \ 771 cxmutstr: cx_map_remove_and_get_mustr, \
1046 char*: cx_map_remove_and_get_str, \ 772 char*: cx_map_remove_and_get_str, \
1047 const char*: cx_map_remove_and_get_str) \ 773 const char*: cx_map_remove_and_get_str) \
1048 (map, key) 774 (map, key, targetbuf)
1049 775
1050 #endif // __cplusplus 776 #endif // __cplusplus
1051 777
1052 #endif // UCX_MAP_H 778 #endif // UCX_MAP_H

mercurial