src/cx/map.h

Thu, 23 May 2024 20:31:37 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 May 2024 20:31:37 +0200
changeset 855
35bcb3216c0d
parent 854
fe0d69d72bcd
child 856
6bbbf219251d
permissions
-rw-r--r--

fix inconsistent use of item_size and elem_size

     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->base.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->base.store_pointer = true;
   187     map->base.elem_size = sizeof(void *);
   188 }
   191 /**
   192  * Deallocates the memory of the specified map.
   193  *
   194  * @param map the map to be destroyed
   195  */
   196 __attribute__((__nonnull__))
   197 static inline void cxMapDestroy(CxMap *map) {
   198     map->cl->destructor(map);
   199 }
   202 /**
   203  * Clears a map by removing all elements.
   204  *
   205  * @param map the map to be cleared
   206  */
   207 __attribute__((__nonnull__))
   208 static inline void cxMapClear(CxMap *map) {
   209     map->cl->clear(map);
   210 }
   213 // TODO: set-like map operations (union, intersect, difference)
   215 /**
   216  * Creates a value iterator for a map.
   217  *
   218  * \note An iterator iterates over all elements successively. Therefore the order
   219  * highly depends on the map implementation and may change arbitrarily when the contents change.
   220  *
   221  * @param map the map to create the iterator for
   222  * @return an iterator for the currently stored values
   223  */
   224 __attribute__((__nonnull__, __warn_unused_result__))
   225 static inline CxIterator cxMapIteratorValues(CxMap const *map) {
   226     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
   227 }
   229 /**
   230  * Creates a key iterator for a map.
   231  *
   232  * The elements of the iterator are keys of type CxHashKey.
   233  *
   234  * \note An iterator iterates over all elements successively. Therefore the order
   235  * highly depends on the map implementation and may change arbitrarily when the contents change.
   236  *
   237  * @param map the map to create the iterator for
   238  * @return an iterator for the currently stored keys
   239  */
   240 __attribute__((__nonnull__, __warn_unused_result__))
   241 static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
   242     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
   243 }
   245 /**
   246  * Creates an iterator for a map.
   247  *
   248  * The elements of the iterator are key/value pairs of type CxMapEntry.
   249  *
   250  * \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.
   252  *
   253  * @param map the map to create the iterator for
   254  * @return an iterator for the currently stored entries
   255  * @see cxMapIteratorKeys()
   256  * @see cxMapIteratorValues()
   257  */
   258 __attribute__((__nonnull__, __warn_unused_result__))
   259 static inline CxIterator cxMapIterator(CxMap const *map) {
   260     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
   261 }
   264 /**
   265  * Creates a mutating iterator over the values of a map.
   266  *
   267  * \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.
   269  *
   270  * @param map the map to create the iterator for
   271  * @return an iterator for the currently stored values
   272  */
   273 __attribute__((__nonnull__, __warn_unused_result__))
   274 CxIterator cxMapMutIteratorValues(CxMap *map);
   276 /**
   277  * Creates a mutating iterator over the keys of a map.
   278  *
   279  * The elements of the iterator are keys of type CxHashKey.
   280  *
   281  * \note An iterator iterates over all elements successively. Therefore the order
   282  * highly depends on the map implementation and may change arbitrarily when the contents change.
   283  *
   284  * @param map the map to create the iterator for
   285  * @return an iterator for the currently stored keys
   286  */
   287 __attribute__((__nonnull__, __warn_unused_result__))
   288 CxIterator cxMapMutIteratorKeys(CxMap *map);
   290 /**
   291  * Creates a mutating iterator for a map.
   292  *
   293  * The elements of the iterator are key/value pairs of type CxMapEntry.
   294  *
   295  * \note An iterator iterates over all elements successively. Therefore the order
   296  * highly depends on the map implementation and may change arbitrarily when the contents change.
   297  *
   298  * @param map the map to create the iterator for
   299  * @return an iterator for the currently stored entries
   300  * @see cxMapMutIteratorKeys()
   301  * @see cxMapMutIteratorValues()
   302  */
   303 __attribute__((__nonnull__, __warn_unused_result__))
   304 CxIterator cxMapMutIterator(CxMap *map);
   306 #ifdef __cplusplus
   307 } // end the extern "C" block here, because we want to start overloading
   309 /**
   310  * Puts a key/value-pair into the map.
   311  *
   312  * @param map the map
   313  * @param key the key
   314  * @param value the value
   315  * @return 0 on success, non-zero value on failure
   316  */
   317 __attribute__((__nonnull__))
   318 static inline int cxMapPut(
   319         CxMap *map,
   320         CxHashKey const &key,
   321         void *value
   322 ) {
   323     return map->cl->put(map, key, value);
   324 }
   327 /**
   328  * Puts a key/value-pair into the map.
   329  *
   330  * @param map the map
   331  * @param key the key
   332  * @param value the value
   333  * @return 0 on success, non-zero value on failure
   334  */
   335 __attribute__((__nonnull__))
   336 static inline int cxMapPut(
   337         CxMap *map,
   338         cxstring const &key,
   339         void *value
   340 ) {
   341     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   342 }
   344 /**
   345  * Puts a key/value-pair into the map.
   346  *
   347  * @param map the map
   348  * @param key the key
   349  * @param value the value
   350  * @return 0 on success, non-zero value on failure
   351  */
   352 __attribute__((__nonnull__))
   353 static inline int cxMapPut(
   354         CxMap *map,
   355         cxmutstr const &key,
   356         void *value
   357 ) {
   358     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   359 }
   361 /**
   362  * Puts a key/value-pair into the map.
   363  *
   364  * @param map the map
   365  * @param key the key
   366  * @param value the value
   367  * @return 0 on success, non-zero value on failure
   368  */
   369 __attribute__((__nonnull__))
   370 static inline int cxMapPut(
   371         CxMap *map,
   372         char const *key,
   373         void *value
   374 ) {
   375     return map->cl->put(map, cx_hash_key_str(key), value);
   376 }
   378 /**
   379  * Retrieves a value by using a key.
   380  *
   381  * @param map the map
   382  * @param key the key
   383  * @return the value
   384  */
   385 __attribute__((__nonnull__, __warn_unused_result__))
   386 static inline void *cxMapGet(
   387         CxMap const *map,
   388         CxHashKey const &key
   389 ) {
   390     return map->cl->get(map, key);
   391 }
   393 /**
   394  * Retrieves a value by using a key.
   395  *
   396  * @param map the map
   397  * @param key the key
   398  * @return the value
   399  */
   400 __attribute__((__nonnull__, __warn_unused_result__))
   401 static inline void *cxMapGet(
   402         CxMap const *map,
   403         cxstring const &key
   404 ) {
   405     return map->cl->get(map, cx_hash_key_cxstr(key));
   406 }
   408 /**
   409  * Retrieves a value by using a key.
   410  *
   411  * @param map the map
   412  * @param key the key
   413  * @return the value
   414  */
   415 __attribute__((__nonnull__, __warn_unused_result__))
   416 static inline void *cxMapGet(
   417         CxMap const *map,
   418         cxmutstr const &key
   419 ) {
   420     return map->cl->get(map, cx_hash_key_cxstr(key));
   421 }
   423 /**
   424  * Retrieves a value by using a key.
   425  *
   426  * @param map the map
   427  * @param key the key
   428  * @return the value
   429  */
   430 __attribute__((__nonnull__, __warn_unused_result__))
   431 static inline void *cxMapGet(
   432         CxMap const *map,
   433         char const *key
   434 ) {
   435     return map->cl->get(map, cx_hash_key_str(key));
   436 }
   438 /**
   439  * Removes a key/value-pair from the map by using the key.
   440  *
   441  * Always invokes the destructor function, if any, on the removed element.
   442  * If this map is storing pointers and you just want to retrieve the pointer
   443  * without invoking the destructor, use cxMapRemoveAndGet().
   444  * If you just want to detach the element from the map without invoking the
   445  * destructor or returning the element, use cxMapDetach().
   446  *
   447  * @param map the map
   448  * @param key the key
   449  * @see cxMapRemoveAndGet()
   450  * @see cxMapDetach()
   451  */
   452 __attribute__((__nonnull__))
   453 static inline void cxMapRemove(
   454         CxMap *map,
   455         CxHashKey const &key
   456 ) {
   457     (void) map->cl->remove(map, key, true);
   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         cxstring const &key
   478 ) {
   479     (void) map->cl->remove(map, cx_hash_key_cxstr(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         cxmutstr 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         char const *key
   522 ) {
   523     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   524 }
   526 /**
   527  * Detaches a key/value-pair from the map by using the key
   528  * without invoking the destructor.
   529  *
   530  * In general, you should only use this function if the map does not own
   531  * the data and there is a valid reference to the data somewhere else
   532  * in the program. In all other cases it is preferable to use
   533  * cxMapRemove() or cxMapRemoveAndGet().
   534  *
   535  * @param map the map
   536  * @param key the key
   537  * @see cxMapRemove()
   538  * @see cxMapRemoveAndGet()
   539  */
   540 __attribute__((__nonnull__))
   541 static inline void cxMapDetach(
   542         CxMap *map,
   543         CxHashKey const &key
   544 ) {
   545     (void) map->cl->remove(map, key, false);
   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         cxstring const &key
   566 ) {
   567     (void) map->cl->remove(map, cx_hash_key_cxstr(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         cxmutstr 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         char const *key
   610 ) {
   611     (void) map->cl->remove(map, cx_hash_key_str(key), false);
   612 }
   614 /**
   615  * Removes a key/value-pair from the map by using the key.
   616  *
   617  * This function can be used when the map is storing pointers,
   618  * in order to retrieve the pointer from the map without invoking
   619  * any destructor function. Sometimes you do not want the pointer
   620  * to be returned - in that case (instead of suppressing the "unused
   621  * result" warning) you can use cxMapDetach().
   622  *
   623  * If this map is not storing pointers, this function behaves like
   624  * cxMapRemove() and returns \c NULL.
   625  *
   626  * @param map the map
   627  * @param key the key
   628  * @return the stored pointer or \c NULL if either the key is not present
   629  * in the map or the map is not storing pointers
   630  * @see cxMapStorePointers()
   631  * @see cxMapDetach()
   632  */
   633 __attribute__((__nonnull__, __warn_unused_result__))
   634 static inline void *cxMapRemoveAndGet(
   635         CxMap *map,
   636         CxHashKey key
   637 ) {
   638     return map->cl->remove(map, key, !map->store_pointer);
   639 }
   641 /**
   642  * Removes a key/value-pair from the map by using the key.
   643  *
   644  * This function can be used when the map is storing pointers,
   645  * in order to retrieve the pointer from the map without invoking
   646  * any destructor function. Sometimes you do not want the pointer
   647  * to be returned - in that case (instead of suppressing the "unused
   648  * result" warning) you can use cxMapDetach().
   649  *
   650  * If this map is not storing pointers, this function behaves like
   651  * cxMapRemove() and returns \c NULL.
   652  *
   653  * @param map the map
   654  * @param key the key
   655  * @return the stored pointer or \c NULL if either the key is not present
   656  * in the map or the map is not storing pointers
   657  * @see cxMapStorePointers()
   658  * @see cxMapDetach()
   659  */
   660 __attribute__((__nonnull__, __warn_unused_result__))
   661 static inline void *cxMapRemoveAndGet(
   662         CxMap *map,
   663         cxstring key
   664 ) {
   665     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   666 }
   668 /**
   669  * Removes a key/value-pair from the map by using the key.
   670  *
   671  * This function can be used when the map is storing pointers,
   672  * in order to retrieve the pointer from the map without invoking
   673  * any destructor function. Sometimes you do not want the pointer
   674  * to be returned - in that case (instead of suppressing the "unused
   675  * result" warning) you can use cxMapDetach().
   676  *
   677  * If this map is not storing pointers, this function behaves like
   678  * cxMapRemove() and returns \c NULL.
   679  *
   680  * @param map the map
   681  * @param key the key
   682  * @return the stored pointer or \c NULL if either the key is not present
   683  * in the map or the map is not storing pointers
   684  * @see cxMapStorePointers()
   685  * @see cxMapDetach()
   686  */
   687 __attribute__((__nonnull__, __warn_unused_result__))
   688 static inline void *cxMapRemoveAndGet(
   689         CxMap *map,
   690         cxmutstr key
   691 ) {
   692     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   693 }
   695 /**
   696  * Removes a key/value-pair from the map by using the key.
   697  *
   698  * This function can be used when the map is storing pointers,
   699  * in order to retrieve the pointer from the map without invoking
   700  * any destructor function. Sometimes you do not want the pointer
   701  * to be returned - in that case (instead of suppressing the "unused
   702  * result" warning) you can use cxMapDetach().
   703  *
   704  * If this map is not storing pointers, this function behaves like
   705  * cxMapRemove() and returns \c NULL.
   706  *
   707  * @param map the map
   708  * @param key the key
   709  * @return the stored pointer or \c NULL if either the key is not present
   710  * in the map or the map is not storing pointers
   711  * @see cxMapStorePointers()
   712  * @see cxMapDetach()
   713  */
   714 __attribute__((__nonnull__, __warn_unused_result__))
   715 static inline void *cxMapRemoveAndGet(
   716         CxMap *map,
   717         char const *key
   718 ) {
   719     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
   720 }
   722 #else // __cplusplus
   724 /**
   725  * Puts a key/value-pair into the map.
   726  *
   727  * @param map the map
   728  * @param key the key
   729  * @param value the value
   730  * @return 0 on success, non-zero value on failure
   731  */
   732 __attribute__((__nonnull__))
   733 static inline int cx_map_put(
   734         CxMap *map,
   735         CxHashKey key,
   736         void *value
   737 ) {
   738     return map->cl->put(map, key, value);
   739 }
   741 /**
   742  * Puts a key/value-pair into the map.
   743  *
   744  * @param map the map
   745  * @param key the key
   746  * @param value the value
   747  * @return 0 on success, non-zero value on failure
   748  */
   749 __attribute__((__nonnull__))
   750 static inline int cx_map_put_cxstr(
   751         CxMap *map,
   752         cxstring key,
   753         void *value
   754 ) {
   755     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   756 }
   758 /**
   759  * Puts a key/value-pair into the map.
   760  *
   761  * @param map the map
   762  * @param key the key
   763  * @param value the value
   764  * @return 0 on success, non-zero value on failure
   765  */
   766 __attribute__((__nonnull__))
   767 static inline int cx_map_put_mustr(
   768         CxMap *map,
   769         cxmutstr key,
   770         void *value
   771 ) {
   772     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   773 }
   775 /**
   776  * Puts a key/value-pair into the map.
   777  *
   778  * @param map the map
   779  * @param key the key
   780  * @param value the value
   781  * @return 0 on success, non-zero value on failure
   782  */
   783 __attribute__((__nonnull__))
   784 static inline int cx_map_put_str(
   785         CxMap *map,
   786         char const *key,
   787         void *value
   788 ) {
   789     return map->cl->put(map, cx_hash_key_str(key), value);
   790 }
   792 /**
   793  * Puts a key/value-pair into the map.
   794  *
   795  * @param map the map
   796  * @param key the key
   797  * @param value the value
   798  * @return 0 on success, non-zero value on failure
   799  */
   800 #define cxMapPut(map, key, value) _Generic((key), \
   801     CxHashKey: cx_map_put,                        \
   802     cxstring: cx_map_put_cxstr,                   \
   803     cxmutstr: cx_map_put_mustr,                   \
   804     char*: cx_map_put_str,                        \
   805     char const*: cx_map_put_str)                  \
   806     (map, key, value)
   808 /**
   809  * Retrieves a value by using a key.
   810  *
   811  * @param map the map
   812  * @param key the key
   813  * @return the value
   814  */
   815 __attribute__((__nonnull__, __warn_unused_result__))
   816 static inline void *cx_map_get(
   817         CxMap const *map,
   818         CxHashKey key
   819 ) {
   820     return map->cl->get(map, key);
   821 }
   823 /**
   824  * Retrieves a value by using a key.
   825  *
   826  * @param map the map
   827  * @param key the key
   828  * @return the value
   829  */
   830 __attribute__((__nonnull__, __warn_unused_result__))
   831 static inline void *cx_map_get_cxstr(
   832         CxMap const *map,
   833         cxstring key
   834 ) {
   835     return map->cl->get(map, cx_hash_key_cxstr(key));
   836 }
   838 /**
   839  * Retrieves a value by using a key.
   840  *
   841  * @param map the map
   842  * @param key the key
   843  * @return the value
   844  */
   845 __attribute__((__nonnull__, __warn_unused_result__))
   846 static inline void *cx_map_get_mustr(
   847         CxMap const *map,
   848         cxmutstr key
   849 ) {
   850     return map->cl->get(map, cx_hash_key_cxstr(key));
   851 }
   853 /**
   854  * Retrieves a value by using a key.
   855  *
   856  * @param map the map
   857  * @param key the key
   858  * @return the value
   859  */
   860 __attribute__((__nonnull__, __warn_unused_result__))
   861 static inline void *cx_map_get_str(
   862         CxMap const *map,
   863         char const *key
   864 ) {
   865     return map->cl->get(map, cx_hash_key_str(key));
   866 }
   868 /**
   869  * Retrieves a value by using a key.
   870  *
   871  * @param map the map
   872  * @param key the key
   873  * @return the value
   874  */
   875 #define cxMapGet(map, key) _Generic((key), \
   876     CxHashKey: cx_map_get,                 \
   877     cxstring: cx_map_get_cxstr,            \
   878     cxmutstr: cx_map_get_mustr,            \
   879     char*: cx_map_get_str,                 \
   880     char const*: cx_map_get_str)           \
   881     (map, key)
   883 /**
   884  * Removes a key/value-pair from the map by using the key.
   885  *
   886  * @param map the map
   887  * @param key the key
   888  */
   889 __attribute__((__nonnull__))
   890 static inline void cx_map_remove(
   891         CxMap *map,
   892         CxHashKey key
   893 ) {
   894     (void) map->cl->remove(map, key, true);
   895 }
   897 /**
   898  * Removes a key/value-pair from the map by using the key.
   899  *
   900  * @param map the map
   901  * @param key the key
   902  */
   903 __attribute__((__nonnull__))
   904 static inline void cx_map_remove_cxstr(
   905         CxMap *map,
   906         cxstring key
   907 ) {
   908     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   909 }
   911 /**
   912  * Removes a key/value-pair from the map by using the key.
   913  *
   914  * @param map the map
   915  * @param key the key
   916  */
   917 __attribute__((__nonnull__))
   918 static inline void cx_map_remove_mustr(
   919         CxMap *map,
   920         cxmutstr key
   921 ) {
   922     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   923 }
   925 /**
   926  * Removes a key/value-pair from the map by using the key.
   927  *
   928  * @param map the map
   929  * @param key the key
   930  */
   931 __attribute__((__nonnull__))
   932 static inline void cx_map_remove_str(
   933         CxMap *map,
   934         char const *key
   935 ) {
   936     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   937 }
   939 /**
   940  * Removes a key/value-pair from the map by using the key.
   941  *
   942  * Always invokes the destructor function, if any, on the removed element.
   943  * If this map is storing pointers and you just want to retrieve the pointer
   944  * without invoking the destructor, use cxMapRemoveAndGet().
   945  * If you just want to detach the element from the map without invoking the
   946  * destructor or returning the element, use cxMapDetach().
   947  *
   948  * @param map the map
   949  * @param key the key
   950  * @see cxMapRemoveAndGet()
   951  * @see cxMapDetach()
   952  */
   953 #define cxMapRemove(map, key) _Generic((key), \
   954     CxHashKey: cx_map_remove,                 \
   955     cxstring: cx_map_remove_cxstr,            \
   956     cxmutstr: cx_map_remove_mustr,            \
   957     char*: cx_map_remove_str,                 \
   958     char const*: cx_map_remove_str)           \
   959     (map, key)
   961 /**
   962  * Detaches a key/value-pair from the map by using the key
   963  * without invoking the destructor.
   964  *
   965  * @param map the map
   966  * @param key the key
   967  */
   968 __attribute__((__nonnull__))
   969 static inline void cx_map_detach(
   970         CxMap *map,
   971         CxHashKey key
   972 ) {
   973     (void) map->cl->remove(map, key, false);
   974 }
   976 /**
   977  * Detaches a key/value-pair from the map by using the key
   978  * without invoking the destructor.
   979  *
   980  * @param map the map
   981  * @param key the key
   982  */
   983 __attribute__((__nonnull__))
   984 static inline void cx_map_detach_cxstr(
   985         CxMap *map,
   986         cxstring key
   987 ) {
   988     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   989 }
   991 /**
   992  * Detaches a key/value-pair from the map by using the key
   993  * without invoking the destructor.
   994  *
   995  * @param map the map
   996  * @param key the key
   997  */
   998 __attribute__((__nonnull__))
   999 static inline void cx_map_detach_mustr(
  1000         CxMap *map,
  1001         cxmutstr key
  1002 ) {
  1003     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
  1006 /**
  1007  * Detaches a key/value-pair from the map by using the key
  1008  * without invoking the destructor.
  1010  * @param map the map
  1011  * @param key the key
  1012  */
  1013 __attribute__((__nonnull__))
  1014 static inline void cx_map_detach_str(
  1015         CxMap *map,
  1016         char const *key
  1017 ) {
  1018     (void) map->cl->remove(map, cx_hash_key_str(key), false);
  1021 /**
  1022  * Detaches a key/value-pair from the map by using the key
  1023  * without invoking the destructor.
  1025  * In general, you should only use this function if the map does not own
  1026  * the data and there is a valid reference to the data somewhere else
  1027  * in the program. In all other cases it is preferable to use
  1028  * cxMapRemove() or cxMapRemoveAndGet().
  1030  * @param map the map
  1031  * @param key the key
  1032  * @see cxMapRemove()
  1033  * @see cxMapRemoveAndGet()
  1034  */
  1035 #define cxMapDetach(map, key) _Generic((key), \
  1036     CxHashKey: cx_map_detach,                 \
  1037     cxstring: cx_map_detach_cxstr,            \
  1038     cxmutstr: cx_map_detach_mustr,            \
  1039     char*: cx_map_detach_str,                 \
  1040     char const*: cx_map_detach_str)           \
  1041     (map, key)
  1043 /**
  1044  * Removes a key/value-pair from the map by using the key.
  1046  * @param map the map
  1047  * @param key the key
  1048  * @return the stored pointer or \c NULL if either the key is not present
  1049  * in the map or the map is not storing pointers
  1050  */
  1051 __attribute__((__nonnull__, __warn_unused_result__))
  1052 static inline void *cx_map_remove_and_get(
  1053         CxMap *map,
  1054         CxHashKey key
  1055 ) {
  1056     return map->cl->remove(map, key, !map->base.store_pointer);
  1059 /**
  1060  * Removes a key/value-pair from the map by using the key.
  1062  * @param map the map
  1063  * @param key the key
  1064  * @return the stored pointer or \c NULL if either the key is not present
  1065  * in the map or the map is not storing pointers
  1066  */
  1067 __attribute__((__nonnull__, __warn_unused_result__))
  1068 static inline void *cx_map_remove_and_get_cxstr(
  1069         CxMap *map,
  1070         cxstring key
  1071 ) {
  1072     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
  1075 /**
  1076  * Removes a key/value-pair from the map by using the key.
  1078  * @param map the map
  1079  * @param key the key
  1080  * @return the stored pointer or \c NULL if either the key is not present
  1081  * in the map or the map is not storing pointers
  1082  */
  1083 __attribute__((__nonnull__, __warn_unused_result__))
  1084 static inline void *cx_map_remove_and_get_mustr(
  1085         CxMap *map,
  1086         cxmutstr key
  1087 ) {
  1088     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->base.store_pointer);
  1091 /**
  1092  * Removes a key/value-pair from the map by using the key.
  1094  * @param map the map
  1095  * @param key the key
  1096  * @return the stored pointer or \c NULL if either the key is not present
  1097  * in the map or the map is not storing pointers
  1098  */
  1099 __attribute__((__nonnull__, __warn_unused_result__))
  1100 static inline void *cx_map_remove_and_get_str(
  1101         CxMap *map,
  1102         char const *key
  1103 ) {
  1104     return map->cl->remove(map, cx_hash_key_str(key), !map->base.store_pointer);
  1107 /**
  1108  * Removes a key/value-pair from the map by using the key.
  1110  * This function can be used when the map is storing pointers,
  1111  * in order to retrieve the pointer from the map without invoking
  1112  * any destructor function. Sometimes you do not want the pointer
  1113  * to be returned - in that case (instead of suppressing the "unused
  1114  * result" warning) you can use cxMapDetach().
  1116  * If this map is not storing pointers, this function behaves like
  1117  * cxMapRemove() and returns \c NULL.
  1119  * @param map the map
  1120  * @param key the key
  1121  * @return the stored pointer or \c NULL if either the key is not present
  1122  * in the map or the map is not storing pointers
  1123  * @see cxMapStorePointers()
  1124  * @see cxMapDetach()
  1125  */
  1126 #define cxMapRemoveAndGet(map, key) _Generic((key), \
  1127     CxHashKey: cx_map_remove_and_get,               \
  1128     cxstring: cx_map_remove_and_get_cxstr,          \
  1129     cxmutstr: cx_map_remove_and_get_mustr,          \
  1130     char*: cx_map_remove_and_get_str,               \
  1131     char const*: cx_map_remove_and_get_str)         \
  1132     (map, key)
  1134 #endif // __cplusplus
  1136 #endif // UCX_MAP_H

mercurial