src/cx/map.h

Sat, 08 Jun 2024 20:08:09 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 08 Jun 2024 20:08:09 +0200
changeset 858
d9ad7904c4c2
parent 857
4d12e34bb130
permissions
-rw-r--r--

add cxIteratorRef() macro

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    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
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 /**
    29  * \file map.h
    30  * \brief Interface for map implementations.
    31  * \author Mike Becker
    32  * \author Olaf Wintermann
    33  * \copyright 2-Clause BSD License
    34  */
    36 #ifndef UCX_MAP_H
    37 #define UCX_MAP_H
    39 #include "common.h"
    40 #include "collection.h"
    41 #include "string.h"
    42 #include "hash_key.h"
    44 #ifdef    __cplusplus
    45 extern "C" {
    46 #endif
    48 /** Type for the UCX map. */
    49 typedef struct cx_map_s CxMap;
    51 /** Type for a map entry. */
    52 typedef struct cx_map_entry_s CxMapEntry;
    54 /** Type for map class definitions. */
    55 typedef struct cx_map_class_s cx_map_class;
    57 /** Structure for the UCX map. */
    58 struct cx_map_s {
    59     /**
    60      * Base attributes.
    61      */
    62     CX_COLLECTION_BASE;
    63     /** The map class definition. */
    64     cx_map_class *cl;
    65 };
    67 /**
    68  * The type of iterator for a map.
    69  */
    70 enum cx_map_iterator_type {
    71     /**
    72      * Iterates over key/value pairs.
    73      */
    74     CX_MAP_ITERATOR_PAIRS,
    75     /**
    76      * Iterates over keys only.
    77      */
    78     CX_MAP_ITERATOR_KEYS,
    79     /**
    80      * Iterates over values only.
    81      */
    82     CX_MAP_ITERATOR_VALUES
    83 };
    85 /**
    86  * The class definition for arbitrary maps.
    87  */
    88 struct cx_map_class_s {
    89     /**
    90      * Deallocates the entire memory.
    91      */
    92     __attribute__((__nonnull__))
    93     void (*destructor)(struct cx_map_s *map);
    95     /**
    96      * Removes all elements.
    97      */
    98     __attribute__((__nonnull__))
    99     void (*clear)(struct cx_map_s *map);
   101     /**
   102      * Add or overwrite an element.
   103      */
   104     __attribute__((__nonnull__))
   105     int (*put)(
   106             CxMap *map,
   107             CxHashKey key,
   108             void *value
   109     );
   111     /**
   112      * Returns an element.
   113      */
   114     __attribute__((__nonnull__, __warn_unused_result__))
   115     void *(*get)(
   116             CxMap const *map,
   117             CxHashKey key
   118     );
   120     /**
   121      * Removes an element.
   122      */
   123     __attribute__((__nonnull__))
   124     void *(*remove)(
   125             CxMap *map,
   126             CxHashKey key,
   127             bool destroy
   128     );
   130     /**
   131      * Creates an iterator for this map.
   132      */
   133     __attribute__((__nonnull__, __warn_unused_result__))
   134     CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
   135 };
   137 /**
   138  * A map entry.
   139  */
   140 struct cx_map_entry_s {
   141     /**
   142      * A pointer to the key.
   143      */
   144     CxHashKey const *key;
   145     /**
   146      * A pointer to the value.
   147      */
   148     void *value;
   149 };
   151 /**
   152  * A shared instance of an empty map.
   153  *
   154  * Writing to that map is undefined.
   155  */
   156 extern CxMap *const cxEmptyMap;
   158 /**
   159  * Advises the map to store copies of the objects (default mode of operation).
   160  *
   161  * Retrieving objects from this map will yield pointers to the copies stored
   162  * within this list.
   163  *
   164  * @param map the map
   165  * @see cxMapStorePointers()
   166  */
   167 __attribute__((__nonnull__))
   168 static inline void cxMapStoreObjects(CxMap *map) {
   169     map->collection.store_pointer = false;
   170 }
   172 /**
   173  * Advises the map to only store pointers to the objects.
   174  *
   175  * Retrieving objects from this list will yield the original pointers stored.
   176  *
   177  * @note This function forcibly sets the element size to the size of a pointer.
   178  * Invoking this function on a non-empty map that already stores copies of
   179  * objects is undefined.
   180  *
   181  * @param map the map
   182  * @see cxMapStoreObjects()
   183  */
   184 __attribute__((__nonnull__))
   185 static inline void cxMapStorePointers(CxMap *map) {
   186     map->collection.store_pointer = true;
   187     map->collection.elem_size = sizeof(void *);
   188 }
   190 /**
   191  * Returns true, if this map is storing pointers instead of the actual data.
   192  *
   193  * @param map
   194  * @return true, if this map is storing pointers
   195  * @see cxMapStorePointers()
   196  */
   197 __attribute__((__nonnull__))
   198 static inline bool cxMapIsStoringPointers(CxMap const *map) {
   199     return map->collection.store_pointer;
   200 }
   202 /**
   203  * Deallocates the memory of the specified map.
   204  *
   205  * @param map the map to be destroyed
   206  */
   207 __attribute__((__nonnull__))
   208 static inline void cxMapDestroy(CxMap *map) {
   209     map->cl->destructor(map);
   210 }
   213 /**
   214  * Clears a map by removing all elements.
   215  *
   216  * @param map the map to be cleared
   217  */
   218 __attribute__((__nonnull__))
   219 static inline void cxMapClear(CxMap *map) {
   220     map->cl->clear(map);
   221 }
   223 /**
   224  * Returns the number of elements in this map.
   225  *
   226  * @param map the map
   227  * @return the number of stored elements
   228  */
   229 __attribute__((__nonnull__))
   230 static inline size_t cxMapSize(CxMap const *map) {
   231     return map->collection.size;
   232 }
   235 // TODO: set-like map operations (union, intersect, difference)
   237 /**
   238  * Creates a value iterator for a map.
   239  *
   240  * \note An iterator iterates over all elements successively. Therefore the order
   241  * highly depends on the map implementation and may change arbitrarily when the contents change.
   242  *
   243  * @param map the map to create the iterator for
   244  * @return an iterator for the currently stored values
   245  */
   246 __attribute__((__nonnull__, __warn_unused_result__))
   247 static inline CxIterator cxMapIteratorValues(CxMap const *map) {
   248     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
   249 }
   251 /**
   252  * Creates a key iterator for a map.
   253  *
   254  * The elements of the iterator are keys of type CxHashKey.
   255  *
   256  * \note An iterator iterates over all elements successively. Therefore the order
   257  * highly depends on the map implementation and may change arbitrarily when the contents change.
   258  *
   259  * @param map the map to create the iterator for
   260  * @return an iterator for the currently stored keys
   261  */
   262 __attribute__((__nonnull__, __warn_unused_result__))
   263 static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
   264     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
   265 }
   267 /**
   268  * Creates an iterator for a map.
   269  *
   270  * The elements of the iterator are key/value pairs of type CxMapEntry.
   271  *
   272  * \note An iterator iterates over all elements successively. Therefore the order
   273  * highly depends on the map implementation and may change arbitrarily when the contents change.
   274  *
   275  * @param map the map to create the iterator for
   276  * @return an iterator for the currently stored entries
   277  * @see cxMapIteratorKeys()
   278  * @see cxMapIteratorValues()
   279  */
   280 __attribute__((__nonnull__, __warn_unused_result__))
   281 static inline CxIterator cxMapIterator(CxMap const *map) {
   282     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
   283 }
   286 /**
   287  * Creates a mutating iterator over the values of a map.
   288  *
   289  * \note An iterator iterates over all elements successively. Therefore the order
   290  * highly depends on the map implementation and may change arbitrarily when the contents change.
   291  *
   292  * @param map the map to create the iterator for
   293  * @return an iterator for the currently stored values
   294  */
   295 __attribute__((__nonnull__, __warn_unused_result__))
   296 CxIterator cxMapMutIteratorValues(CxMap *map);
   298 /**
   299  * Creates a mutating iterator over the keys of a map.
   300  *
   301  * The elements of the iterator are keys of type CxHashKey.
   302  *
   303  * \note An iterator iterates over all elements successively. Therefore the order
   304  * highly depends on the map implementation and may change arbitrarily when the contents change.
   305  *
   306  * @param map the map to create the iterator for
   307  * @return an iterator for the currently stored keys
   308  */
   309 __attribute__((__nonnull__, __warn_unused_result__))
   310 CxIterator cxMapMutIteratorKeys(CxMap *map);
   312 /**
   313  * Creates a mutating iterator for a map.
   314  *
   315  * The elements of the iterator are key/value pairs of type CxMapEntry.
   316  *
   317  * \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.
   319  *
   320  * @param map the map to create the iterator for
   321  * @return an iterator for the currently stored entries
   322  * @see cxMapMutIteratorKeys()
   323  * @see cxMapMutIteratorValues()
   324  */
   325 __attribute__((__nonnull__, __warn_unused_result__))
   326 CxIterator cxMapMutIterator(CxMap *map);
   328 #ifdef __cplusplus
   329 } // end the extern "C" block here, because we want to start overloading
   331 /**
   332  * Puts a key/value-pair into the map.
   333  *
   334  * @param map the map
   335  * @param key the key
   336  * @param value the value
   337  * @return 0 on success, non-zero value on failure
   338  */
   339 __attribute__((__nonnull__))
   340 static inline int cxMapPut(
   341         CxMap *map,
   342         CxHashKey const &key,
   343         void *value
   344 ) {
   345     return map->cl->put(map, key, value);
   346 }
   349 /**
   350  * Puts a key/value-pair into the map.
   351  *
   352  * @param map the map
   353  * @param key the key
   354  * @param value the value
   355  * @return 0 on success, non-zero value on failure
   356  */
   357 __attribute__((__nonnull__))
   358 static inline int cxMapPut(
   359         CxMap *map,
   360         cxstring const &key,
   361         void *value
   362 ) {
   363     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   364 }
   366 /**
   367  * Puts a key/value-pair into the map.
   368  *
   369  * @param map the map
   370  * @param key the key
   371  * @param value the value
   372  * @return 0 on success, non-zero value on failure
   373  */
   374 __attribute__((__nonnull__))
   375 static inline int cxMapPut(
   376         CxMap *map,
   377         cxmutstr const &key,
   378         void *value
   379 ) {
   380     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   381 }
   383 /**
   384  * Puts a key/value-pair into the map.
   385  *
   386  * @param map the map
   387  * @param key the key
   388  * @param value the value
   389  * @return 0 on success, non-zero value on failure
   390  */
   391 __attribute__((__nonnull__))
   392 static inline int cxMapPut(
   393         CxMap *map,
   394         char const *key,
   395         void *value
   396 ) {
   397     return map->cl->put(map, cx_hash_key_str(key), value);
   398 }
   400 /**
   401  * Retrieves a value by using a key.
   402  *
   403  * @param map the map
   404  * @param key the key
   405  * @return the value
   406  */
   407 __attribute__((__nonnull__, __warn_unused_result__))
   408 static inline void *cxMapGet(
   409         CxMap const *map,
   410         CxHashKey const &key
   411 ) {
   412     return map->cl->get(map, key);
   413 }
   415 /**
   416  * Retrieves a value by using a key.
   417  *
   418  * @param map the map
   419  * @param key the key
   420  * @return the value
   421  */
   422 __attribute__((__nonnull__, __warn_unused_result__))
   423 static inline void *cxMapGet(
   424         CxMap const *map,
   425         cxstring const &key
   426 ) {
   427     return map->cl->get(map, cx_hash_key_cxstr(key));
   428 }
   430 /**
   431  * Retrieves a value by using a key.
   432  *
   433  * @param map the map
   434  * @param key the key
   435  * @return the value
   436  */
   437 __attribute__((__nonnull__, __warn_unused_result__))
   438 static inline void *cxMapGet(
   439         CxMap const *map,
   440         cxmutstr const &key
   441 ) {
   442     return map->cl->get(map, cx_hash_key_cxstr(key));
   443 }
   445 /**
   446  * Retrieves a value by using a key.
   447  *
   448  * @param map the map
   449  * @param key the key
   450  * @return the value
   451  */
   452 __attribute__((__nonnull__, __warn_unused_result__))
   453 static inline void *cxMapGet(
   454         CxMap const *map,
   455         char const *key
   456 ) {
   457     return map->cl->get(map, cx_hash_key_str(key));
   458 }
   460 /**
   461  * Removes a key/value-pair from the map by using the key.
   462  *
   463  * Always invokes the destructor function, if any, on the removed element.
   464  * If this map is storing pointers and you just want to retrieve the pointer
   465  * without invoking the destructor, use cxMapRemoveAndGet().
   466  * If you just want to detach the element from the map without invoking the
   467  * destructor or returning the element, use cxMapDetach().
   468  *
   469  * @param map the map
   470  * @param key the key
   471  * @see cxMapRemoveAndGet()
   472  * @see cxMapDetach()
   473  */
   474 __attribute__((__nonnull__))
   475 static inline void cxMapRemove(
   476         CxMap *map,
   477         CxHashKey const &key
   478 ) {
   479     (void) map->cl->remove(map, key, true);
   480 }
   482 /**
   483  * Removes a key/value-pair from the map by using the key.
   484  *
   485  * Always invokes the destructor function, if any, on the removed element.
   486  * If this map is storing pointers and you just want to retrieve the pointer
   487  * without invoking the destructor, use cxMapRemoveAndGet().
   488  * If you just want to detach the element from the map without invoking the
   489  * destructor or returning the element, use cxMapDetach().
   490  *
   491  * @param map the map
   492  * @param key the key
   493  * @see cxMapRemoveAndGet()
   494  * @see cxMapDetach()
   495  */
   496 __attribute__((__nonnull__))
   497 static inline void cxMapRemove(
   498         CxMap *map,
   499         cxstring const &key
   500 ) {
   501     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   502 }
   504 /**
   505  * Removes a key/value-pair from the map by using the key.
   506  *
   507  * Always invokes the destructor function, if any, on the removed element.
   508  * If this map is storing pointers and you just want to retrieve the pointer
   509  * without invoking the destructor, use cxMapRemoveAndGet().
   510  * If you just want to detach the element from the map without invoking the
   511  * destructor or returning the element, use cxMapDetach().
   512  *
   513  * @param map the map
   514  * @param key the key
   515  * @see cxMapRemoveAndGet()
   516  * @see cxMapDetach()
   517  */
   518 __attribute__((__nonnull__))
   519 static inline void cxMapRemove(
   520         CxMap *map,
   521         cxmutstr const &key
   522 ) {
   523     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   524 }
   526 /**
   527  * Removes a key/value-pair from the map by using the key.
   528  *
   529  * Always invokes the destructor function, if any, on the removed element.
   530  * If this map is storing pointers and you just want to retrieve the pointer
   531  * without invoking the destructor, use cxMapRemoveAndGet().
   532  * If you just want to detach the element from the map without invoking the
   533  * destructor or returning the element, use cxMapDetach().
   534  *
   535  * @param map the map
   536  * @param key the key
   537  * @see cxMapRemoveAndGet()
   538  * @see cxMapDetach()
   539  */
   540 __attribute__((__nonnull__))
   541 static inline void cxMapRemove(
   542         CxMap *map,
   543         char const *key
   544 ) {
   545     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   546 }
   548 /**
   549  * Detaches a key/value-pair from the map by using the key
   550  * without invoking the destructor.
   551  *
   552  * In general, you should only use this function if the map does not own
   553  * the data and there is a valid reference to the data somewhere else
   554  * in the program. In all other cases it is preferable to use
   555  * cxMapRemove() or cxMapRemoveAndGet().
   556  *
   557  * @param map the map
   558  * @param key the key
   559  * @see cxMapRemove()
   560  * @see cxMapRemoveAndGet()
   561  */
   562 __attribute__((__nonnull__))
   563 static inline void cxMapDetach(
   564         CxMap *map,
   565         CxHashKey const &key
   566 ) {
   567     (void) map->cl->remove(map, key, false);
   568 }
   570 /**
   571  * Detaches a key/value-pair from the map by using the key
   572  * without invoking the destructor.
   573  *
   574  * In general, you should only use this function if the map does not own
   575  * the data and there is a valid reference to the data somewhere else
   576  * in the program. In all other cases it is preferable to use
   577  * cxMapRemove() or cxMapRemoveAndGet().
   578  *
   579  * @param map the map
   580  * @param key the key
   581  * @see cxMapRemove()
   582  * @see cxMapRemoveAndGet()
   583  */
   584 __attribute__((__nonnull__))
   585 static inline void cxMapDetach(
   586         CxMap *map,
   587         cxstring const &key
   588 ) {
   589     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   590 }
   592 /**
   593  * Detaches a key/value-pair from the map by using the key
   594  * without invoking the destructor.
   595  *
   596  * In general, you should only use this function if the map does not own
   597  * the data and there is a valid reference to the data somewhere else
   598  * in the program. In all other cases it is preferable to use
   599  * cxMapRemove() or cxMapRemoveAndGet().
   600  *
   601  * @param map the map
   602  * @param key the key
   603  * @see cxMapRemove()
   604  * @see cxMapRemoveAndGet()
   605  */
   606 __attribute__((__nonnull__))
   607 static inline void cxMapDetach(
   608         CxMap *map,
   609         cxmutstr const &key
   610 ) {
   611     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   612 }
   614 /**
   615  * Detaches a key/value-pair from the map by using the key
   616  * without invoking the destructor.
   617  *
   618  * In general, you should only use this function if the map does not own
   619  * the data and there is a valid reference to the data somewhere else
   620  * in the program. In all other cases it is preferable to use
   621  * cxMapRemove() or cxMapRemoveAndGet().
   622  *
   623  * @param map the map
   624  * @param key the key
   625  * @see cxMapRemove()
   626  * @see cxMapRemoveAndGet()
   627  */
   628 __attribute__((__nonnull__))
   629 static inline void cxMapDetach(
   630         CxMap *map,
   631         char const *key
   632 ) {
   633     (void) map->cl->remove(map, cx_hash_key_str(key), false);
   634 }
   636 /**
   637  * Removes a key/value-pair from the map by using the key.
   638  *
   639  * This function can be used when the map is storing pointers,
   640  * in order to retrieve the pointer from the map without invoking
   641  * any destructor function. Sometimes you do not want the pointer
   642  * to be returned - in that case (instead of suppressing the "unused
   643  * result" warning) you can use cxMapDetach().
   644  *
   645  * If this map is not storing pointers, this function behaves like
   646  * cxMapRemove() and returns \c NULL.
   647  *
   648  * @param map the map
   649  * @param key the key
   650  * @return the stored pointer or \c NULL if either the key is not present
   651  * in the map or the map is not storing pointers
   652  * @see cxMapStorePointers()
   653  * @see cxMapDetach()
   654  */
   655 __attribute__((__nonnull__, __warn_unused_result__))
   656 static inline void *cxMapRemoveAndGet(
   657         CxMap *map,
   658         CxHashKey key
   659 ) {
   660     return map->cl->remove(map, key, !map->store_pointer);
   661 }
   663 /**
   664  * Removes a key/value-pair from the map by using the key.
   665  *
   666  * This function can be used when the map is storing pointers,
   667  * in order to retrieve the pointer from the map without invoking
   668  * any destructor function. Sometimes you do not want the pointer
   669  * to be returned - in that case (instead of suppressing the "unused
   670  * result" warning) you can use cxMapDetach().
   671  *
   672  * If this map is not storing pointers, this function behaves like
   673  * cxMapRemove() and returns \c NULL.
   674  *
   675  * @param map the map
   676  * @param key the key
   677  * @return the stored pointer or \c NULL if either the key is not present
   678  * in the map or the map is not storing pointers
   679  * @see cxMapStorePointers()
   680  * @see cxMapDetach()
   681  */
   682 __attribute__((__nonnull__, __warn_unused_result__))
   683 static inline void *cxMapRemoveAndGet(
   684         CxMap *map,
   685         cxstring key
   686 ) {
   687     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   688 }
   690 /**
   691  * Removes a key/value-pair from the map by using the key.
   692  *
   693  * This function can be used when the map is storing pointers,
   694  * in order to retrieve the pointer from the map without invoking
   695  * any destructor function. Sometimes you do not want the pointer
   696  * to be returned - in that case (instead of suppressing the "unused
   697  * result" warning) you can use cxMapDetach().
   698  *
   699  * If this map is not storing pointers, this function behaves like
   700  * cxMapRemove() and returns \c NULL.
   701  *
   702  * @param map the map
   703  * @param key the key
   704  * @return the stored pointer or \c NULL if either the key is not present
   705  * in the map or the map is not storing pointers
   706  * @see cxMapStorePointers()
   707  * @see cxMapDetach()
   708  */
   709 __attribute__((__nonnull__, __warn_unused_result__))
   710 static inline void *cxMapRemoveAndGet(
   711         CxMap *map,
   712         cxmutstr key
   713 ) {
   714     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   715 }
   717 /**
   718  * Removes a key/value-pair from the map by using the key.
   719  *
   720  * This function can be used when the map is storing pointers,
   721  * in order to retrieve the pointer from the map without invoking
   722  * any destructor function. Sometimes you do not want the pointer
   723  * to be returned - in that case (instead of suppressing the "unused
   724  * result" warning) you can use cxMapDetach().
   725  *
   726  * If this map is not storing pointers, this function behaves like
   727  * cxMapRemove() and returns \c NULL.
   728  *
   729  * @param map the map
   730  * @param key the key
   731  * @return the stored pointer or \c NULL if either the key is not present
   732  * in the map or the map is not storing pointers
   733  * @see cxMapStorePointers()
   734  * @see cxMapDetach()
   735  */
   736 __attribute__((__nonnull__, __warn_unused_result__))
   737 static inline void *cxMapRemoveAndGet(
   738         CxMap *map,
   739         char const *key
   740 ) {
   741     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
   742 }
   744 #else // __cplusplus
   746 /**
   747  * Puts a key/value-pair into the map.
   748  *
   749  * @param map the map
   750  * @param key the key
   751  * @param value the value
   752  * @return 0 on success, non-zero value on failure
   753  */
   754 __attribute__((__nonnull__))
   755 static inline int cx_map_put(
   756         CxMap *map,
   757         CxHashKey key,
   758         void *value
   759 ) {
   760     return map->cl->put(map, key, value);
   761 }
   763 /**
   764  * Puts a key/value-pair into the map.
   765  *
   766  * @param map the map
   767  * @param key the key
   768  * @param value the value
   769  * @return 0 on success, non-zero value on failure
   770  */
   771 __attribute__((__nonnull__))
   772 static inline int cx_map_put_cxstr(
   773         CxMap *map,
   774         cxstring key,
   775         void *value
   776 ) {
   777     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   778 }
   780 /**
   781  * Puts a key/value-pair into the map.
   782  *
   783  * @param map the map
   784  * @param key the key
   785  * @param value the value
   786  * @return 0 on success, non-zero value on failure
   787  */
   788 __attribute__((__nonnull__))
   789 static inline int cx_map_put_mustr(
   790         CxMap *map,
   791         cxmutstr key,
   792         void *value
   793 ) {
   794     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   795 }
   797 /**
   798  * Puts a key/value-pair into the map.
   799  *
   800  * @param map the map
   801  * @param key the key
   802  * @param value the value
   803  * @return 0 on success, non-zero value on failure
   804  */
   805 __attribute__((__nonnull__))
   806 static inline int cx_map_put_str(
   807         CxMap *map,
   808         char const *key,
   809         void *value
   810 ) {
   811     return map->cl->put(map, cx_hash_key_str(key), value);
   812 }
   814 /**
   815  * Puts a key/value-pair into the map.
   816  *
   817  * @param map the map
   818  * @param key the key
   819  * @param value the value
   820  * @return 0 on success, non-zero value on failure
   821  */
   822 #define cxMapPut(map, key, value) _Generic((key), \
   823     CxHashKey: cx_map_put,                        \
   824     cxstring: cx_map_put_cxstr,                   \
   825     cxmutstr: cx_map_put_mustr,                   \
   826     char*: cx_map_put_str,                        \
   827     char const*: cx_map_put_str)                  \
   828     (map, key, value)
   830 /**
   831  * Retrieves a value by using a key.
   832  *
   833  * @param map the map
   834  * @param key the key
   835  * @return the value
   836  */
   837 __attribute__((__nonnull__, __warn_unused_result__))
   838 static inline void *cx_map_get(
   839         CxMap const *map,
   840         CxHashKey key
   841 ) {
   842     return map->cl->get(map, key);
   843 }
   845 /**
   846  * Retrieves a value by using a key.
   847  *
   848  * @param map the map
   849  * @param key the key
   850  * @return the value
   851  */
   852 __attribute__((__nonnull__, __warn_unused_result__))
   853 static inline void *cx_map_get_cxstr(
   854         CxMap const *map,
   855         cxstring key
   856 ) {
   857     return map->cl->get(map, cx_hash_key_cxstr(key));
   858 }
   860 /**
   861  * Retrieves a value by using a key.
   862  *
   863  * @param map the map
   864  * @param key the key
   865  * @return the value
   866  */
   867 __attribute__((__nonnull__, __warn_unused_result__))
   868 static inline void *cx_map_get_mustr(
   869         CxMap const *map,
   870         cxmutstr key
   871 ) {
   872     return map->cl->get(map, cx_hash_key_cxstr(key));
   873 }
   875 /**
   876  * Retrieves a value by using a key.
   877  *
   878  * @param map the map
   879  * @param key the key
   880  * @return the value
   881  */
   882 __attribute__((__nonnull__, __warn_unused_result__))
   883 static inline void *cx_map_get_str(
   884         CxMap const *map,
   885         char const *key
   886 ) {
   887     return map->cl->get(map, cx_hash_key_str(key));
   888 }
   890 /**
   891  * Retrieves a value by using a key.
   892  *
   893  * @param map the map
   894  * @param key the key
   895  * @return the value
   896  */
   897 #define cxMapGet(map, key) _Generic((key), \
   898     CxHashKey: cx_map_get,                 \
   899     cxstring: cx_map_get_cxstr,            \
   900     cxmutstr: cx_map_get_mustr,            \
   901     char*: cx_map_get_str,                 \
   902     char const*: cx_map_get_str)           \
   903     (map, key)
   905 /**
   906  * Removes a key/value-pair from the map by using the key.
   907  *
   908  * @param map the map
   909  * @param key the key
   910  */
   911 __attribute__((__nonnull__))
   912 static inline void cx_map_remove(
   913         CxMap *map,
   914         CxHashKey key
   915 ) {
   916     (void) map->cl->remove(map, key, true);
   917 }
   919 /**
   920  * Removes a key/value-pair from the map by using the key.
   921  *
   922  * @param map the map
   923  * @param key the key
   924  */
   925 __attribute__((__nonnull__))
   926 static inline void cx_map_remove_cxstr(
   927         CxMap *map,
   928         cxstring key
   929 ) {
   930     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   931 }
   933 /**
   934  * Removes a key/value-pair from the map by using the key.
   935  *
   936  * @param map the map
   937  * @param key the key
   938  */
   939 __attribute__((__nonnull__))
   940 static inline void cx_map_remove_mustr(
   941         CxMap *map,
   942         cxmutstr key
   943 ) {
   944     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   945 }
   947 /**
   948  * Removes a key/value-pair from the map by using the key.
   949  *
   950  * @param map the map
   951  * @param key the key
   952  */
   953 __attribute__((__nonnull__))
   954 static inline void cx_map_remove_str(
   955         CxMap *map,
   956         char const *key
   957 ) {
   958     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   959 }
   961 /**
   962  * Removes a key/value-pair from the map by using the key.
   963  *
   964  * Always invokes the destructor function, if any, on the removed element.
   965  * If this map is storing pointers and you just want to retrieve the pointer
   966  * without invoking the destructor, use cxMapRemoveAndGet().
   967  * If you just want to detach the element from the map without invoking the
   968  * destructor or returning the element, use cxMapDetach().
   969  *
   970  * @param map the map
   971  * @param key the key
   972  * @see cxMapRemoveAndGet()
   973  * @see cxMapDetach()
   974  */
   975 #define cxMapRemove(map, key) _Generic((key), \
   976     CxHashKey: cx_map_remove,                 \
   977     cxstring: cx_map_remove_cxstr,            \
   978     cxmutstr: cx_map_remove_mustr,            \
   979     char*: cx_map_remove_str,                 \
   980     char const*: cx_map_remove_str)           \
   981     (map, key)
   983 /**
   984  * Detaches a key/value-pair from the map by using the key
   985  * without invoking the destructor.
   986  *
   987  * @param map the map
   988  * @param key the key
   989  */
   990 __attribute__((__nonnull__))
   991 static inline void cx_map_detach(
   992         CxMap *map,
   993         CxHashKey key
   994 ) {
   995     (void) map->cl->remove(map, key, false);
   996 }
   998 /**
   999  * Detaches a key/value-pair from the map by using the key
  1000  * without invoking the destructor.
  1002  * @param map the map
  1003  * @param key the key
  1004  */
  1005 __attribute__((__nonnull__))
  1006 static inline void cx_map_detach_cxstr(
  1007         CxMap *map,
  1008         cxstring key
  1009 ) {
  1010     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
  1013 /**
  1014  * Detaches a key/value-pair from the map by using the key
  1015  * without invoking the destructor.
  1017  * @param map the map
  1018  * @param key the key
  1019  */
  1020 __attribute__((__nonnull__))
  1021 static inline void cx_map_detach_mustr(
  1022         CxMap *map,
  1023         cxmutstr key
  1024 ) {
  1025     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
  1028 /**
  1029  * Detaches a key/value-pair from the map by using the key
  1030  * without invoking the destructor.
  1032  * @param map the map
  1033  * @param key the key
  1034  */
  1035 __attribute__((__nonnull__))
  1036 static inline void cx_map_detach_str(
  1037         CxMap *map,
  1038         char const *key
  1039 ) {
  1040     (void) map->cl->remove(map, cx_hash_key_str(key), false);
  1043 /**
  1044  * Detaches a key/value-pair from the map by using the key
  1045  * without invoking the destructor.
  1047  * In general, you should only use this function if the map does not own
  1048  * the data and there is a valid reference to the data somewhere else
  1049  * in the program. In all other cases it is preferable to use
  1050  * cxMapRemove() or cxMapRemoveAndGet().
  1052  * @param map the map
  1053  * @param key the key
  1054  * @see cxMapRemove()
  1055  * @see cxMapRemoveAndGet()
  1056  */
  1057 #define cxMapDetach(map, key) _Generic((key), \
  1058     CxHashKey: cx_map_detach,                 \
  1059     cxstring: cx_map_detach_cxstr,            \
  1060     cxmutstr: cx_map_detach_mustr,            \
  1061     char*: cx_map_detach_str,                 \
  1062     char const*: cx_map_detach_str)           \
  1063     (map, key)
  1065 /**
  1066  * Removes a key/value-pair from the map by using the key.
  1068  * @param map the map
  1069  * @param key the key
  1070  * @return the stored pointer or \c NULL if either the key is not present
  1071  * in the map or the map is not storing pointers
  1072  */
  1073 __attribute__((__nonnull__, __warn_unused_result__))
  1074 static inline void *cx_map_remove_and_get(
  1075         CxMap *map,
  1076         CxHashKey key
  1077 ) {
  1078     return map->cl->remove(map, key, !map->collection.store_pointer);
  1081 /**
  1082  * Removes a key/value-pair from the map by using the key.
  1084  * @param map the map
  1085  * @param key the key
  1086  * @return the stored pointer or \c NULL if either the key is not present
  1087  * in the map or the map is not storing pointers
  1088  */
  1089 __attribute__((__nonnull__, __warn_unused_result__))
  1090 static inline void *cx_map_remove_and_get_cxstr(
  1091         CxMap *map,
  1092         cxstring key
  1093 ) {
  1094     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
  1097 /**
  1098  * Removes a key/value-pair from the map by using the key.
  1100  * @param map the map
  1101  * @param key the key
  1102  * @return the stored pointer or \c NULL if either the key is not present
  1103  * in the map or the map is not storing pointers
  1104  */
  1105 __attribute__((__nonnull__, __warn_unused_result__))
  1106 static inline void *cx_map_remove_and_get_mustr(
  1107         CxMap *map,
  1108         cxmutstr key
  1109 ) {
  1110     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->collection.store_pointer);
  1113 /**
  1114  * Removes a key/value-pair from the map by using the key.
  1116  * @param map the map
  1117  * @param key the key
  1118  * @return the stored pointer or \c NULL if either the key is not present
  1119  * in the map or the map is not storing pointers
  1120  */
  1121 __attribute__((__nonnull__, __warn_unused_result__))
  1122 static inline void *cx_map_remove_and_get_str(
  1123         CxMap *map,
  1124         char const *key
  1125 ) {
  1126     return map->cl->remove(map, cx_hash_key_str(key), !map->collection.store_pointer);
  1129 /**
  1130  * Removes a key/value-pair from the map by using the key.
  1132  * This function can be used when the map is storing pointers,
  1133  * in order to retrieve the pointer from the map without invoking
  1134  * any destructor function. Sometimes you do not want the pointer
  1135  * to be returned - in that case (instead of suppressing the "unused
  1136  * result" warning) you can use cxMapDetach().
  1138  * If this map is not storing pointers, this function behaves like
  1139  * cxMapRemove() and returns \c NULL.
  1141  * @param map the map
  1142  * @param key the key
  1143  * @return the stored pointer or \c NULL if either the key is not present
  1144  * in the map or the map is not storing pointers
  1145  * @see cxMapStorePointers()
  1146  * @see cxMapDetach()
  1147  */
  1148 #define cxMapRemoveAndGet(map, key) _Generic((key), \
  1149     CxHashKey: cx_map_remove_and_get,               \
  1150     cxstring: cx_map_remove_and_get_cxstr,          \
  1151     cxmutstr: cx_map_remove_and_get_mustr,          \
  1152     char*: cx_map_remove_and_get_str,               \
  1153     char const*: cx_map_remove_and_get_str)         \
  1154     (map, key)
  1156 #endif // __cplusplus
  1158 #endif // UCX_MAP_H

mercurial