src/cx/map.h

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

author
Mike Becker <universe@uap-core.de>
date
Fri, 21 Apr 2023 19:50:43 +0200
changeset 691
65baf7f45ac8
parent 689
5d0244c6fa3e
child 692
6ac92936cd44
permissions
-rw-r--r--

bring a generic interface to CxMap

     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         char const *key,
   365         void *value
   366 ) {
   367     return map->cl->put(map, cx_hash_key_str(key), value);
   368 }
   370 /**
   371  * Retrieves a value by using a key.
   372  *
   373  * @param map the map
   374  * @param key the key
   375  * @return the value
   376  */
   377 __attribute__((__nonnull__, __warn_unused_result__))
   378 static inline void *cxMapGet(
   379         CxMap const *map,
   380         CxHashKey const &key
   381 ) {
   382     return map->cl->get(map, key);
   383 }
   385 /**
   386  * Retrieves a value by using a key.
   387  *
   388  * @param map the map
   389  * @param key the key
   390  * @return the value
   391  */
   392 __attribute__((__nonnull__, __warn_unused_result__))
   393 static inline void *cxMapGet(
   394         CxMap const *map,
   395         cxstring const &key
   396 ) {
   397     return map->cl->get(map, cx_hash_key_cxstr(key));
   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         char const *key
   411 ) {
   412     return map->cl->get(map, cx_hash_key_str(key));
   413 }
   415 /**
   416  * Removes a key/value-pair from the map by using the key.
   417  *
   418  * Always invokes the destructor function, if any, on the removed element.
   419  * If this map is storing pointers and you just want to retrieve the pointer
   420  * without invoking the destructor, use cxMapRemoveAndGet().
   421  * If you just want to detach the element from the map without invoking the
   422  * destructor or returning the element, use cxMapDetach().
   423  *
   424  * @param map the map
   425  * @param key the key
   426  * @see cxMapRemoveAndGet()
   427  * @see cxMapDetach()
   428  */
   429 __attribute__((__nonnull__))
   430 static inline void cxMapRemove(
   431         CxMap *map,
   432         CxHashKey const &key
   433 ) {
   434     (void) map->cl->remove(map, key, true);
   435 }
   437 /**
   438  * Removes a key/value-pair from the map by using the key.
   439  *
   440  * Always invokes the destructor function, if any, on the removed element.
   441  * If this map is storing pointers and you just want to retrieve the pointer
   442  * without invoking the destructor, use cxMapRemoveAndGet().
   443  * If you just want to detach the element from the map without invoking the
   444  * destructor or returning the element, use cxMapDetach().
   445  *
   446  * @param map the map
   447  * @param key the key
   448  * @see cxMapRemoveAndGet()
   449  * @see cxMapDetach()
   450  */
   451 __attribute__((__nonnull__))
   452 static inline void cxMapRemove(
   453         CxMap *map,
   454         cxstring const &key
   455 ) {
   456     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   457 }
   459 /**
   460  * Removes a key/value-pair from the map by using the key.
   461  *
   462  * Always invokes the destructor function, if any, on the removed element.
   463  * If this map is storing pointers and you just want to retrieve the pointer
   464  * without invoking the destructor, use cxMapRemoveAndGet().
   465  * If you just want to detach the element from the map without invoking the
   466  * destructor or returning the element, use cxMapDetach().
   467  *
   468  * @param map the map
   469  * @param key the key
   470  * @see cxMapRemoveAndGet()
   471  * @see cxMapDetach()
   472  */
   473 __attribute__((__nonnull__))
   474 static inline void cxMapRemove(
   475         CxMap *map,
   476         char const *key
   477 ) {
   478     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   479 }
   481 /**
   482  * Detaches a key/value-pair from the map by using the key
   483  * without invoking the destructor.
   484  *
   485  * In general, you should only use this function if the map does not own
   486  * the data and there is a valid reference to the data somewhere else
   487  * in the program. In all other cases it is preferable to use
   488  * cxMapRemove() or cxMapRemoveAndGet().
   489  *
   490  * @param map the map
   491  * @param key the key
   492  * @see cxMapRemove()
   493  * @see cxMapRemoveAndGet()
   494  */
   495 __attribute__((__nonnull__))
   496 static inline void cxMapDetach(
   497         CxMap *map,
   498         CxHashKey const &key
   499 ) {
   500     (void) map->cl->remove(map, key, false);
   501 }
   503 /**
   504  * Detaches a key/value-pair from the map by using the key
   505  * without invoking the destructor.
   506  *
   507  * In general, you should only use this function if the map does not own
   508  * the data and there is a valid reference to the data somewhere else
   509  * in the program. In all other cases it is preferable to use
   510  * cxMapRemove() or cxMapRemoveAndGet().
   511  *
   512  * @param map the map
   513  * @param key the key
   514  * @see cxMapRemove()
   515  * @see cxMapRemoveAndGet()
   516  */
   517 __attribute__((__nonnull__))
   518 static inline void cxMapDetach(
   519         CxMap *map,
   520         cxstring const &key
   521 ) {
   522     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   523 }
   525 /**
   526  * Detaches a key/value-pair from the map by using the key
   527  * without invoking the destructor.
   528  *
   529  * In general, you should only use this function if the map does not own
   530  * the data and there is a valid reference to the data somewhere else
   531  * in the program. In all other cases it is preferable to use
   532  * cxMapRemove() or cxMapRemoveAndGet().
   533  *
   534  * @param map the map
   535  * @param key the key
   536  * @see cxMapRemove()
   537  * @see cxMapRemoveAndGet()
   538  */
   539 __attribute__((__nonnull__))
   540 static inline void cxMapDetach(
   541         CxMap *map,
   542         char const *key
   543 ) {
   544     (void) map->cl->remove(map, cx_hash_key_str(key), false);
   545 }
   547 /**
   548  * Removes a key/value-pair from the map by using the key.
   549  *
   550  * This function can be used when the map is storing pointers,
   551  * in order to retrieve the pointer from the map without invoking
   552  * any destructor function. Sometimes you do not want the pointer
   553  * to be returned - in that case (instead of suppressing the "unused
   554  * result" warning) you can use cxMapDetach().
   555  *
   556  * If this map is not storing pointers, this function behaves like
   557  * cxMapRemove() and returns \c NULL.
   558  *
   559  * @param map the map
   560  * @param key the key
   561  * @return the stored pointer or \c NULL if either the key is not present
   562  * in the map or the map is not storing pointers
   563  * @see cxMapStorePointers()
   564  * @see cxMapDetach()
   565  */
   566 __attribute__((__nonnull__, __warn_unused_result__))
   567 static inline void *cxMapRemoveAndGet(
   568         CxMap *map,
   569         CxHashKey key
   570 ) {
   571     return map->cl->remove(map, key, !map->store_pointer);
   572 }
   574 /**
   575  * Removes a key/value-pair from the map by using the key.
   576  *
   577  * This function can be used when the map is storing pointers,
   578  * in order to retrieve the pointer from the map without invoking
   579  * any destructor function. Sometimes you do not want the pointer
   580  * to be returned - in that case (instead of suppressing the "unused
   581  * result" warning) you can use cxMapDetach().
   582  *
   583  * If this map is not storing pointers, this function behaves like
   584  * cxMapRemove() and returns \c NULL.
   585  *
   586  * @param map the map
   587  * @param key the key
   588  * @return the stored pointer or \c NULL if either the key is not present
   589  * in the map or the map is not storing pointers
   590  * @see cxMapStorePointers()
   591  * @see cxMapDetach()
   592  */
   593 __attribute__((__nonnull__, __warn_unused_result__))
   594 static inline void *cxMapRemoveAndGet(
   595         CxMap *map,
   596         cxstring key
   597 ) {
   598     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   599 }
   601 /**
   602  * Removes a key/value-pair from the map by using the key.
   603  *
   604  * This function can be used when the map is storing pointers,
   605  * in order to retrieve the pointer from the map without invoking
   606  * any destructor function. Sometimes you do not want the pointer
   607  * to be returned - in that case (instead of suppressing the "unused
   608  * result" warning) you can use cxMapDetach().
   609  *
   610  * If this map is not storing pointers, this function behaves like
   611  * cxMapRemove() and returns \c NULL.
   612  *
   613  * @param map the map
   614  * @param key the key
   615  * @return the stored pointer or \c NULL if either the key is not present
   616  * in the map or the map is not storing pointers
   617  * @see cxMapStorePointers()
   618  * @see cxMapDetach()
   619  */
   620 __attribute__((__nonnull__, __warn_unused_result__))
   621 static inline void *cxMapRemoveAndGet(
   622         CxMap *map,
   623         char const *key
   624 ) {
   625     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
   626 }
   628 #else // __cplusplus
   630 /**
   631  * Puts a key/value-pair into the map.
   632  *
   633  * @param map the map
   634  * @param key the key
   635  * @param value the value
   636  * @return 0 on success, non-zero value on failure
   637  */
   638 __attribute__((__nonnull__))
   639 static inline int cx_map_put(
   640         CxMap *map,
   641         CxHashKey key,
   642         void *value
   643 ) {
   644     return map->cl->put(map, key, value);
   645 }
   647 /**
   648  * Puts a key/value-pair into the map.
   649  *
   650  * @param map the map
   651  * @param key the key
   652  * @param value the value
   653  * @return 0 on success, non-zero value on failure
   654  */
   655 __attribute__((__nonnull__))
   656 static inline int cx_map_put_cxstr(
   657         CxMap *map,
   658         cxstring key,
   659         void *value
   660 ) {
   661     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   662 }
   664 /**
   665  * Puts a key/value-pair into the map.
   666  *
   667  * @param map the map
   668  * @param key the key
   669  * @param value the value
   670  * @return 0 on success, non-zero value on failure
   671  */
   672 __attribute__((__nonnull__))
   673 static inline int cx_map_put_str(
   674         CxMap *map,
   675         char const *key,
   676         void *value
   677 ) {
   678     return map->cl->put(map, cx_hash_key_str(key), value);
   679 }
   681 /**
   682  * Puts a key/value-pair into the map.
   683  *
   684  * @param map the map
   685  * @param key the key
   686  * @param value the value
   687  * @return 0 on success, non-zero value on failure
   688  */
   689 #define cxMapPut(map, key, value) _Generic((key), \
   690     CxHashKey: cx_map_put,                        \
   691     cxstring: cx_map_put_cxstr,                   \
   692     char*: cx_map_put_str)                        \
   693     (map, key, value)
   695 /**
   696  * Retrieves a value by using a key.
   697  *
   698  * @param map the map
   699  * @param key the key
   700  * @return the value
   701  */
   702 __attribute__((__nonnull__, __warn_unused_result__))
   703 static inline void *cx_map_get(
   704         CxMap const *map,
   705         CxHashKey key
   706 ) {
   707     return map->cl->get(map, key);
   708 }
   710 /**
   711  * Retrieves a value by using a key.
   712  *
   713  * @param map the map
   714  * @param key the key
   715  * @return the value
   716  */
   717 __attribute__((__nonnull__, __warn_unused_result__))
   718 static inline void *cx_map_get_cxstr(
   719         CxMap const *map,
   720         cxstring key
   721 ) {
   722     return map->cl->get(map, cx_hash_key_cxstr(key));
   723 }
   725 /**
   726  * Retrieves a value by using a key.
   727  *
   728  * @param map the map
   729  * @param key the key
   730  * @return the value
   731  */
   732 __attribute__((__nonnull__, __warn_unused_result__))
   733 static inline void *cx_map_get_str(
   734         CxMap const *map,
   735         char const *key
   736 ) {
   737     return map->cl->get(map, cx_hash_key_str(key));
   738 }
   740 /**
   741  * Retrieves a value by using a key.
   742  *
   743  * @param map the map
   744  * @param key the key
   745  * @return the value
   746  */
   747 #define cxMapGet(map, key) _Generic((key), \
   748     CxHashKey: cx_map_get,                 \
   749     cxstring: cx_map_get_cxstr,            \
   750     char*: cx_map_get_str)                 \
   751     (map, key)
   753 /**
   754  * Removes a key/value-pair from the map by using the key.
   755  *
   756  * @param map the map
   757  * @param key the key
   758  */
   759 __attribute__((__nonnull__))
   760 static inline void cx_map_remove(
   761         CxMap *map,
   762         CxHashKey key
   763 ) {
   764     (void) map->cl->remove(map, key, true);
   765 }
   767 /**
   768  * Removes a key/value-pair from the map by using the key.
   769  *
   770  * @param map the map
   771  * @param key the key
   772  */
   773 __attribute__((__nonnull__))
   774 static inline void cx_map_remove_cxstr(
   775         CxMap *map,
   776         cxstring key
   777 ) {
   778     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   779 }
   781 /**
   782  * Removes a key/value-pair from the map by using the key.
   783  *
   784  * @param map the map
   785  * @param key the key
   786  */
   787 __attribute__((__nonnull__))
   788 static inline void cx_map_remove_str(
   789         CxMap *map,
   790         char const *key
   791 ) {
   792     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   793 }
   795 /**
   796  * Removes a key/value-pair from the map by using the key.
   797  *
   798  * Always invokes the destructor function, if any, on the removed element.
   799  * If this map is storing pointers and you just want to retrieve the pointer
   800  * without invoking the destructor, use cxMapRemoveAndGet().
   801  * If you just want to detach the element from the map without invoking the
   802  * destructor or returning the element, use cxMapDetach().
   803  *
   804  * @param map the map
   805  * @param key the key
   806  * @see cxMapRemoveAndGet()
   807  * @see cxMapDetach()
   808  */
   809 #define cxMapRemove(map, key) _Generic((key), \
   810     CxHashKey: cx_map_remove,                 \
   811     cxstring: cx_map_remove_cxstr,            \
   812     char*: cx_map_remove_str)                 \
   813     (map, key)
   815 /**
   816  * Detaches a key/value-pair from the map by using the key
   817  * without invoking the destructor.
   818  *
   819  * @param map the map
   820  * @param key the key
   821  */
   822 __attribute__((__nonnull__))
   823 static inline void cx_map_detach(
   824         CxMap *map,
   825         CxHashKey key
   826 ) {
   827     (void) map->cl->remove(map, key, false);
   828 }
   830 /**
   831  * Detaches a key/value-pair from the map by using the key
   832  * without invoking the destructor.
   833  *
   834  * @param map the map
   835  * @param key the key
   836  */
   837 __attribute__((__nonnull__))
   838 static inline void cx_map_detach_cxstr(
   839         CxMap *map,
   840         cxstring key
   841 ) {
   842     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   843 }
   845 /**
   846  * Detaches a key/value-pair from the map by using the key
   847  * without invoking the destructor.
   848  *
   849  * @param map the map
   850  * @param key the key
   851  */
   852 __attribute__((__nonnull__))
   853 static inline void cx_map_detach_str(
   854         CxMap *map,
   855         char const *key
   856 ) {
   857     (void) map->cl->remove(map, cx_hash_key_str(key), false);
   858 }
   860 /**
   861  * Detaches a key/value-pair from the map by using the key
   862  * without invoking the destructor.
   863  *
   864  * In general, you should only use this function if the map does not own
   865  * the data and there is a valid reference to the data somewhere else
   866  * in the program. In all other cases it is preferable to use
   867  * cxMapRemove() or cxMapRemoveAndGet().
   868  *
   869  * @param map the map
   870  * @param key the key
   871  * @see cxMapRemove()
   872  * @see cxMapRemoveAndGet()
   873  */
   874 #define cxMapDetach(map, key) _Generic((key), \
   875     CxHashKey: cx_map_detach,                 \
   876     cxstring: cx_map_detach_cxstr,            \
   877     char*: cx_map_detach_str)                 \
   878     (map, key)
   880 /**
   881  * Removes a key/value-pair from the map by using the key.
   882  *
   883  * @param map the map
   884  * @param key the key
   885  * @return the stored pointer or \c NULL if either the key is not present
   886  * in the map or the map is not storing pointers
   887  */
   888 __attribute__((__nonnull__, __warn_unused_result__))
   889 static inline void *cx_map_remove_and_get(
   890         CxMap *map,
   891         CxHashKey key
   892 ) {
   893     return map->cl->remove(map, key, !map->store_pointer);
   894 }
   896 /**
   897  * Removes a key/value-pair from the map by using the key.
   898  *
   899  * @param map the map
   900  * @param key the key
   901  * @return the stored pointer or \c NULL if either the key is not present
   902  * in the map or the map is not storing pointers
   903  */
   904 __attribute__((__nonnull__, __warn_unused_result__))
   905 static inline void *cx_map_remove_and_get_cxstr(
   906         CxMap *map,
   907         cxstring key
   908 ) {
   909     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   910 }
   912 /**
   913  * Removes a key/value-pair from the map by using the key.
   914  *
   915  * @param map the map
   916  * @param key the key
   917  * @return the stored pointer or \c NULL if either the key is not present
   918  * in the map or the map is not storing pointers
   919  */
   920 __attribute__((__nonnull__, __warn_unused_result__))
   921 static inline void *cx_map_remove_and_get_str(
   922         CxMap *map,
   923         char const *key
   924 ) {
   925     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
   926 }
   928 /**
   929  * Removes a key/value-pair from the map by using the key.
   930  *
   931  * This function can be used when the map is storing pointers,
   932  * in order to retrieve the pointer from the map without invoking
   933  * any destructor function. Sometimes you do not want the pointer
   934  * to be returned - in that case (instead of suppressing the "unused
   935  * result" warning) you can use cxMapDetach().
   936  *
   937  * If this map is not storing pointers, this function behaves like
   938  * cxMapRemove() and returns \c NULL.
   939  *
   940  * @param map the map
   941  * @param key the key
   942  * @return the stored pointer or \c NULL if either the key is not present
   943  * in the map or the map is not storing pointers
   944  * @see cxMapStorePointers()
   945  * @see cxMapDetach()
   946  */
   947 #define cxMapRemoveAndGet(map, key) _Generic((key), \
   948     CxHashKey: cx_map_remove_and_get,               \
   949     cxstring: cx_map_remove_and_get_cxstr,          \
   950     char*: cx_map_remove_and_get_str)               \
   951     (map, key)
   953 #endif // __cplusplus
   955 #endif // UCX_MAP_H

mercurial