src/ucx/cx/map.h

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

mercurial