src/cx/map.h

Fri, 21 Apr 2023 20:50:19 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 21 Apr 2023 20:50:19 +0200
changeset 694
ac827d873c17
parent 692
6ac92936cd44
child 706
8c6edaccaef1
permissions
-rw-r--r--

fix missing controlling-expression for char const*

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

mercurial