ucx/cx/map.h

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

mercurial