src/cx/map.h

Sun, 21 May 2023 14:37:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 21 May 2023 14:37:56 +0200
changeset 706
8c6edaccaef1
parent 694
ac827d873c17
child 709
1e8ba59e7911
permissions
-rw-r--r--

add empty map implementation - fixes #259

     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 extern CxMap *const cxEmptyMap;
   163 /**
   164  * Advises the map to store copies of the objects (default mode of operation).
   165  *
   166  * Retrieving objects from this map will yield pointers to the copies stored
   167  * within this list.
   168  *
   169  * @param map the map
   170  * @see cxMapStorePointers()
   171  */
   172 __attribute__((__nonnull__))
   173 static inline void cxMapStoreObjects(CxMap *map) {
   174     map->store_pointer = false;
   175 }
   177 /**
   178  * Advises the map to only store pointers to the objects.
   179  *
   180  * Retrieving objects from this list will yield the original pointers stored.
   181  *
   182  * @note This function forcibly sets the element size to the size of a pointer.
   183  * Invoking this function on a non-empty map that already stores copies of
   184  * objects is undefined.
   185  *
   186  * @param map the map
   187  * @see cxMapStoreObjects()
   188  */
   189 __attribute__((__nonnull__))
   190 static inline void cxMapStorePointers(CxMap *map) {
   191     map->store_pointer = true;
   192     map->item_size = sizeof(void *);
   193 }
   196 /**
   197  * Deallocates the memory of the specified map.
   198  *
   199  * @param map the map to be destroyed
   200  */
   201 __attribute__((__nonnull__))
   202 static inline void cxMapDestroy(CxMap *map) {
   203     map->cl->destructor(map);
   204 }
   207 /**
   208  * Clears a map by removing all elements.
   209  *
   210  * @param map the map to be cleared
   211  */
   212 __attribute__((__nonnull__))
   213 static inline void cxMapClear(CxMap *map) {
   214     map->cl->clear(map);
   215 }
   218 // TODO: set-like map operations (union, intersect, difference)
   220 /**
   221  * Creates a value iterator for a map.
   222  *
   223  * \note An iterator iterates over all elements successively. Therefore the order
   224  * highly depends on the map implementation and may change arbitrarily when the contents change.
   225  *
   226  * @param map the map to create the iterator for
   227  * @return an iterator for the currently stored values
   228  */
   229 __attribute__((__nonnull__, __warn_unused_result__))
   230 static inline CxIterator cxMapIteratorValues(CxMap *map) {
   231     return map->cl->iterator_values(map);
   232 }
   234 /**
   235  * Creates a key iterator for a map.
   236  *
   237  * The elements of the iterator are keys of type CxHashKey.
   238  *
   239  * \note An iterator iterates over all elements successively. Therefore the order
   240  * highly depends on the map implementation and may change arbitrarily when the contents change.
   241  *
   242  * @param map the map to create the iterator for
   243  * @return an iterator for the currently stored keys
   244  */
   245 __attribute__((__nonnull__, __warn_unused_result__))
   246 static inline CxIterator cxMapIteratorKeys(CxMap *map) {
   247     return map->cl->iterator_keys(map);
   248 }
   250 /**
   251  * Creates an iterator for a map.
   252  *
   253  * The elements of the iterator are key/value pairs of type CxMapEntry.
   254  *
   255  * \note An iterator iterates over all elements successively. Therefore the order
   256  * highly depends on the map implementation and may change arbitrarily when the contents change.
   257  *
   258  * @param map the map to create the iterator for
   259  * @return an iterator for the currently stored entries
   260  * @see cxMapIteratorKeys()
   261  * @see cxMapIteratorValues()
   262  */
   263 __attribute__((__nonnull__, __warn_unused_result__))
   264 static inline CxIterator cxMapIterator(CxMap *map) {
   265     return map->cl->iterator(map);
   266 }
   269 /**
   270  * Creates a mutating iterator over the values of a map.
   271  *
   272  * \note An iterator iterates over all elements successively. Therefore the order
   273  * highly depends on the map implementation and may change arbitrarily when the contents change.
   274  *
   275  * @param map the map to create the iterator for
   276  * @return an iterator for the currently stored values
   277  */
   278 __attribute__((__nonnull__, __warn_unused_result__))
   279 static inline CxMutIterator cxMapMutIteratorValues(CxMap *map) {
   280     return map->cl->mut_iterator_values(map);
   281 }
   283 /**
   284  * Creates a mutating iterator over the keys of a map.
   285  *
   286  * The elements of the iterator are keys of type CxHashKey.
   287  *
   288  * \note An iterator iterates over all elements successively. Therefore the order
   289  * highly depends on the map implementation and may change arbitrarily when the contents change.
   290  *
   291  * @param map the map to create the iterator for
   292  * @return an iterator for the currently stored keys
   293  */
   294 __attribute__((__nonnull__, __warn_unused_result__))
   295 static inline CxMutIterator cxMapMutIteratorKeys(CxMap *map) {
   296     return map->cl->mut_iterator_keys(map);
   297 }
   299 /**
   300  * Creates a mutating iterator for a map.
   301  *
   302  * The elements of the iterator are key/value pairs of type CxMapEntry.
   303  *
   304  * \note An iterator iterates over all elements successively. Therefore the order
   305  * highly depends on the map implementation and may change arbitrarily when the contents change.
   306  *
   307  * @param map the map to create the iterator for
   308  * @return an iterator for the currently stored entries
   309  * @see cxMapMutIteratorKeys()
   310  * @see cxMapMutIteratorValues()
   311  */
   312 __attribute__((__nonnull__, __warn_unused_result__))
   313 static inline CxMutIterator cxMapMutIterator(CxMap *map) {
   314     return map->cl->mut_iterator(map);
   315 }
   317 #ifdef __cplusplus
   318 } // end the extern "C" block here, because we want to start overloading
   320 /**
   321  * Puts a key/value-pair into the map.
   322  *
   323  * @param map the map
   324  * @param key the key
   325  * @param value the value
   326  * @return 0 on success, non-zero value on failure
   327  */
   328 __attribute__((__nonnull__))
   329 static inline int cxMapPut(
   330         CxMap *map,
   331         CxHashKey const &key,
   332         void *value
   333 ) {
   334     return map->cl->put(map, key, value);
   335 }
   338 /**
   339  * Puts a key/value-pair into the map.
   340  *
   341  * @param map the map
   342  * @param key the key
   343  * @param value the value
   344  * @return 0 on success, non-zero value on failure
   345  */
   346 __attribute__((__nonnull__))
   347 static inline int cxMapPut(
   348         CxMap *map,
   349         cxstring const &key,
   350         void *value
   351 ) {
   352     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   353 }
   355 /**
   356  * Puts a key/value-pair into the map.
   357  *
   358  * @param map the map
   359  * @param key the key
   360  * @param value the value
   361  * @return 0 on success, non-zero value on failure
   362  */
   363 __attribute__((__nonnull__))
   364 static inline int cxMapPut(
   365         CxMap *map,
   366         cxmutstr const &key,
   367         void *value
   368 ) {
   369     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   370 }
   372 /**
   373  * Puts a key/value-pair into the map.
   374  *
   375  * @param map the map
   376  * @param key the key
   377  * @param value the value
   378  * @return 0 on success, non-zero value on failure
   379  */
   380 __attribute__((__nonnull__))
   381 static inline int cxMapPut(
   382         CxMap *map,
   383         char const *key,
   384         void *value
   385 ) {
   386     return map->cl->put(map, cx_hash_key_str(key), value);
   387 }
   389 /**
   390  * Retrieves a value by using a key.
   391  *
   392  * @param map the map
   393  * @param key the key
   394  * @return the value
   395  */
   396 __attribute__((__nonnull__, __warn_unused_result__))
   397 static inline void *cxMapGet(
   398         CxMap const *map,
   399         CxHashKey const &key
   400 ) {
   401     return map->cl->get(map, key);
   402 }
   404 /**
   405  * Retrieves a value by using a key.
   406  *
   407  * @param map the map
   408  * @param key the key
   409  * @return the value
   410  */
   411 __attribute__((__nonnull__, __warn_unused_result__))
   412 static inline void *cxMapGet(
   413         CxMap const *map,
   414         cxstring const &key
   415 ) {
   416     return map->cl->get(map, cx_hash_key_cxstr(key));
   417 }
   419 /**
   420  * Retrieves a value by using a key.
   421  *
   422  * @param map the map
   423  * @param key the key
   424  * @return the value
   425  */
   426 __attribute__((__nonnull__, __warn_unused_result__))
   427 static inline void *cxMapGet(
   428         CxMap const *map,
   429         cxmutstr const &key
   430 ) {
   431     return map->cl->get(map, cx_hash_key_cxstr(key));
   432 }
   434 /**
   435  * Retrieves a value by using a key.
   436  *
   437  * @param map the map
   438  * @param key the key
   439  * @return the value
   440  */
   441 __attribute__((__nonnull__, __warn_unused_result__))
   442 static inline void *cxMapGet(
   443         CxMap const *map,
   444         char const *key
   445 ) {
   446     return map->cl->get(map, cx_hash_key_str(key));
   447 }
   449 /**
   450  * Removes a key/value-pair from the map by using the key.
   451  *
   452  * Always invokes the destructor function, if any, on the removed element.
   453  * If this map is storing pointers and you just want to retrieve the pointer
   454  * without invoking the destructor, use cxMapRemoveAndGet().
   455  * If you just want to detach the element from the map without invoking the
   456  * destructor or returning the element, use cxMapDetach().
   457  *
   458  * @param map the map
   459  * @param key the key
   460  * @see cxMapRemoveAndGet()
   461  * @see cxMapDetach()
   462  */
   463 __attribute__((__nonnull__))
   464 static inline void cxMapRemove(
   465         CxMap *map,
   466         CxHashKey const &key
   467 ) {
   468     (void) map->cl->remove(map, key, true);
   469 }
   471 /**
   472  * Removes a key/value-pair from the map by using the key.
   473  *
   474  * Always invokes the destructor function, if any, on the removed element.
   475  * If this map is storing pointers and you just want to retrieve the pointer
   476  * without invoking the destructor, use cxMapRemoveAndGet().
   477  * If you just want to detach the element from the map without invoking the
   478  * destructor or returning the element, use cxMapDetach().
   479  *
   480  * @param map the map
   481  * @param key the key
   482  * @see cxMapRemoveAndGet()
   483  * @see cxMapDetach()
   484  */
   485 __attribute__((__nonnull__))
   486 static inline void cxMapRemove(
   487         CxMap *map,
   488         cxstring const &key
   489 ) {
   490     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   491 }
   493 /**
   494  * Removes a key/value-pair from the map by using the key.
   495  *
   496  * Always invokes the destructor function, if any, on the removed element.
   497  * If this map is storing pointers and you just want to retrieve the pointer
   498  * without invoking the destructor, use cxMapRemoveAndGet().
   499  * If you just want to detach the element from the map without invoking the
   500  * destructor or returning the element, use cxMapDetach().
   501  *
   502  * @param map the map
   503  * @param key the key
   504  * @see cxMapRemoveAndGet()
   505  * @see cxMapDetach()
   506  */
   507 __attribute__((__nonnull__))
   508 static inline void cxMapRemove(
   509         CxMap *map,
   510         cxmutstr const &key
   511 ) {
   512     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   513 }
   515 /**
   516  * Removes a key/value-pair from the map by using the key.
   517  *
   518  * Always invokes the destructor function, if any, on the removed element.
   519  * If this map is storing pointers and you just want to retrieve the pointer
   520  * without invoking the destructor, use cxMapRemoveAndGet().
   521  * If you just want to detach the element from the map without invoking the
   522  * destructor or returning the element, use cxMapDetach().
   523  *
   524  * @param map the map
   525  * @param key the key
   526  * @see cxMapRemoveAndGet()
   527  * @see cxMapDetach()
   528  */
   529 __attribute__((__nonnull__))
   530 static inline void cxMapRemove(
   531         CxMap *map,
   532         char const *key
   533 ) {
   534     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   535 }
   537 /**
   538  * Detaches a key/value-pair from the map by using the key
   539  * without invoking the destructor.
   540  *
   541  * In general, you should only use this function if the map does not own
   542  * the data and there is a valid reference to the data somewhere else
   543  * in the program. In all other cases it is preferable to use
   544  * cxMapRemove() or cxMapRemoveAndGet().
   545  *
   546  * @param map the map
   547  * @param key the key
   548  * @see cxMapRemove()
   549  * @see cxMapRemoveAndGet()
   550  */
   551 __attribute__((__nonnull__))
   552 static inline void cxMapDetach(
   553         CxMap *map,
   554         CxHashKey const &key
   555 ) {
   556     (void) map->cl->remove(map, key, false);
   557 }
   559 /**
   560  * Detaches a key/value-pair from the map by using the key
   561  * without invoking the destructor.
   562  *
   563  * In general, you should only use this function if the map does not own
   564  * the data and there is a valid reference to the data somewhere else
   565  * in the program. In all other cases it is preferable to use
   566  * cxMapRemove() or cxMapRemoveAndGet().
   567  *
   568  * @param map the map
   569  * @param key the key
   570  * @see cxMapRemove()
   571  * @see cxMapRemoveAndGet()
   572  */
   573 __attribute__((__nonnull__))
   574 static inline void cxMapDetach(
   575         CxMap *map,
   576         cxstring const &key
   577 ) {
   578     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   579 }
   581 /**
   582  * Detaches a key/value-pair from the map by using the key
   583  * without invoking the destructor.
   584  *
   585  * In general, you should only use this function if the map does not own
   586  * the data and there is a valid reference to the data somewhere else
   587  * in the program. In all other cases it is preferable to use
   588  * cxMapRemove() or cxMapRemoveAndGet().
   589  *
   590  * @param map the map
   591  * @param key the key
   592  * @see cxMapRemove()
   593  * @see cxMapRemoveAndGet()
   594  */
   595 __attribute__((__nonnull__))
   596 static inline void cxMapDetach(
   597         CxMap *map,
   598         cxmutstr const &key
   599 ) {
   600     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
   601 }
   603 /**
   604  * Detaches a key/value-pair from the map by using the key
   605  * without invoking the destructor.
   606  *
   607  * In general, you should only use this function if the map does not own
   608  * the data and there is a valid reference to the data somewhere else
   609  * in the program. In all other cases it is preferable to use
   610  * cxMapRemove() or cxMapRemoveAndGet().
   611  *
   612  * @param map the map
   613  * @param key the key
   614  * @see cxMapRemove()
   615  * @see cxMapRemoveAndGet()
   616  */
   617 __attribute__((__nonnull__))
   618 static inline void cxMapDetach(
   619         CxMap *map,
   620         char const *key
   621 ) {
   622     (void) map->cl->remove(map, cx_hash_key_str(key), false);
   623 }
   625 /**
   626  * Removes a key/value-pair from the map by using the key.
   627  *
   628  * This function can be used when the map is storing pointers,
   629  * in order to retrieve the pointer from the map without invoking
   630  * any destructor function. Sometimes you do not want the pointer
   631  * to be returned - in that case (instead of suppressing the "unused
   632  * result" warning) you can use cxMapDetach().
   633  *
   634  * If this map is not storing pointers, this function behaves like
   635  * cxMapRemove() and returns \c NULL.
   636  *
   637  * @param map the map
   638  * @param key the key
   639  * @return the stored pointer or \c NULL if either the key is not present
   640  * in the map or the map is not storing pointers
   641  * @see cxMapStorePointers()
   642  * @see cxMapDetach()
   643  */
   644 __attribute__((__nonnull__, __warn_unused_result__))
   645 static inline void *cxMapRemoveAndGet(
   646         CxMap *map,
   647         CxHashKey key
   648 ) {
   649     return map->cl->remove(map, key, !map->store_pointer);
   650 }
   652 /**
   653  * Removes a key/value-pair from the map by using the key.
   654  *
   655  * This function can be used when the map is storing pointers,
   656  * in order to retrieve the pointer from the map without invoking
   657  * any destructor function. Sometimes you do not want the pointer
   658  * to be returned - in that case (instead of suppressing the "unused
   659  * result" warning) you can use cxMapDetach().
   660  *
   661  * If this map is not storing pointers, this function behaves like
   662  * cxMapRemove() and returns \c NULL.
   663  *
   664  * @param map the map
   665  * @param key the key
   666  * @return the stored pointer or \c NULL if either the key is not present
   667  * in the map or the map is not storing pointers
   668  * @see cxMapStorePointers()
   669  * @see cxMapDetach()
   670  */
   671 __attribute__((__nonnull__, __warn_unused_result__))
   672 static inline void *cxMapRemoveAndGet(
   673         CxMap *map,
   674         cxstring key
   675 ) {
   676     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   677 }
   679 /**
   680  * Removes a key/value-pair from the map by using the key.
   681  *
   682  * This function can be used when the map is storing pointers,
   683  * in order to retrieve the pointer from the map without invoking
   684  * any destructor function. Sometimes you do not want the pointer
   685  * to be returned - in that case (instead of suppressing the "unused
   686  * result" warning) you can use cxMapDetach().
   687  *
   688  * If this map is not storing pointers, this function behaves like
   689  * cxMapRemove() and returns \c NULL.
   690  *
   691  * @param map the map
   692  * @param key the key
   693  * @return the stored pointer or \c NULL if either the key is not present
   694  * in the map or the map is not storing pointers
   695  * @see cxMapStorePointers()
   696  * @see cxMapDetach()
   697  */
   698 __attribute__((__nonnull__, __warn_unused_result__))
   699 static inline void *cxMapRemoveAndGet(
   700         CxMap *map,
   701         cxmutstr key
   702 ) {
   703     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
   704 }
   706 /**
   707  * Removes a key/value-pair from the map by using the key.
   708  *
   709  * This function can be used when the map is storing pointers,
   710  * in order to retrieve the pointer from the map without invoking
   711  * any destructor function. Sometimes you do not want the pointer
   712  * to be returned - in that case (instead of suppressing the "unused
   713  * result" warning) you can use cxMapDetach().
   714  *
   715  * If this map is not storing pointers, this function behaves like
   716  * cxMapRemove() and returns \c NULL.
   717  *
   718  * @param map the map
   719  * @param key the key
   720  * @return the stored pointer or \c NULL if either the key is not present
   721  * in the map or the map is not storing pointers
   722  * @see cxMapStorePointers()
   723  * @see cxMapDetach()
   724  */
   725 __attribute__((__nonnull__, __warn_unused_result__))
   726 static inline void *cxMapRemoveAndGet(
   727         CxMap *map,
   728         char const *key
   729 ) {
   730     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
   731 }
   733 #else // __cplusplus
   735 /**
   736  * Puts a key/value-pair into the map.
   737  *
   738  * @param map the map
   739  * @param key the key
   740  * @param value the value
   741  * @return 0 on success, non-zero value on failure
   742  */
   743 __attribute__((__nonnull__))
   744 static inline int cx_map_put(
   745         CxMap *map,
   746         CxHashKey key,
   747         void *value
   748 ) {
   749     return map->cl->put(map, key, value);
   750 }
   752 /**
   753  * Puts a key/value-pair into the map.
   754  *
   755  * @param map the map
   756  * @param key the key
   757  * @param value the value
   758  * @return 0 on success, non-zero value on failure
   759  */
   760 __attribute__((__nonnull__))
   761 static inline int cx_map_put_cxstr(
   762         CxMap *map,
   763         cxstring key,
   764         void *value
   765 ) {
   766     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   767 }
   769 /**
   770  * Puts a key/value-pair into the map.
   771  *
   772  * @param map the map
   773  * @param key the key
   774  * @param value the value
   775  * @return 0 on success, non-zero value on failure
   776  */
   777 __attribute__((__nonnull__))
   778 static inline int cx_map_put_mustr(
   779         CxMap *map,
   780         cxmutstr key,
   781         void *value
   782 ) {
   783     return map->cl->put(map, cx_hash_key_cxstr(key), value);
   784 }
   786 /**
   787  * Puts a key/value-pair into the map.
   788  *
   789  * @param map the map
   790  * @param key the key
   791  * @param value the value
   792  * @return 0 on success, non-zero value on failure
   793  */
   794 __attribute__((__nonnull__))
   795 static inline int cx_map_put_str(
   796         CxMap *map,
   797         char const *key,
   798         void *value
   799 ) {
   800     return map->cl->put(map, cx_hash_key_str(key), value);
   801 }
   803 /**
   804  * Puts a key/value-pair into the map.
   805  *
   806  * @param map the map
   807  * @param key the key
   808  * @param value the value
   809  * @return 0 on success, non-zero value on failure
   810  */
   811 #define cxMapPut(map, key, value) _Generic((key), \
   812     CxHashKey: cx_map_put,                        \
   813     cxstring: cx_map_put_cxstr,                   \
   814     cxmutstr: cx_map_put_mustr,                   \
   815     char*: cx_map_put_str,                        \
   816     char const*: cx_map_put_str)                  \
   817     (map, key, value)
   819 /**
   820  * Retrieves a value by using a key.
   821  *
   822  * @param map the map
   823  * @param key the key
   824  * @return the value
   825  */
   826 __attribute__((__nonnull__, __warn_unused_result__))
   827 static inline void *cx_map_get(
   828         CxMap const *map,
   829         CxHashKey key
   830 ) {
   831     return map->cl->get(map, key);
   832 }
   834 /**
   835  * Retrieves a value by using a key.
   836  *
   837  * @param map the map
   838  * @param key the key
   839  * @return the value
   840  */
   841 __attribute__((__nonnull__, __warn_unused_result__))
   842 static inline void *cx_map_get_cxstr(
   843         CxMap const *map,
   844         cxstring key
   845 ) {
   846     return map->cl->get(map, cx_hash_key_cxstr(key));
   847 }
   849 /**
   850  * Retrieves a value by using a key.
   851  *
   852  * @param map the map
   853  * @param key the key
   854  * @return the value
   855  */
   856 __attribute__((__nonnull__, __warn_unused_result__))
   857 static inline void *cx_map_get_mustr(
   858         CxMap const *map,
   859         cxmutstr key
   860 ) {
   861     return map->cl->get(map, cx_hash_key_cxstr(key));
   862 }
   864 /**
   865  * Retrieves a value by using a key.
   866  *
   867  * @param map the map
   868  * @param key the key
   869  * @return the value
   870  */
   871 __attribute__((__nonnull__, __warn_unused_result__))
   872 static inline void *cx_map_get_str(
   873         CxMap const *map,
   874         char const *key
   875 ) {
   876     return map->cl->get(map, cx_hash_key_str(key));
   877 }
   879 /**
   880  * Retrieves a value by using a key.
   881  *
   882  * @param map the map
   883  * @param key the key
   884  * @return the value
   885  */
   886 #define cxMapGet(map, key) _Generic((key), \
   887     CxHashKey: cx_map_get,                 \
   888     cxstring: cx_map_get_cxstr,            \
   889     cxmutstr: cx_map_get_mustr,            \
   890     char*: cx_map_get_str,                 \
   891     char const*: cx_map_get_str)           \
   892     (map, key)
   894 /**
   895  * Removes a key/value-pair from the map by using the key.
   896  *
   897  * @param map the map
   898  * @param key the key
   899  */
   900 __attribute__((__nonnull__))
   901 static inline void cx_map_remove(
   902         CxMap *map,
   903         CxHashKey key
   904 ) {
   905     (void) map->cl->remove(map, key, true);
   906 }
   908 /**
   909  * Removes a key/value-pair from the map by using the key.
   910  *
   911  * @param map the map
   912  * @param key the key
   913  */
   914 __attribute__((__nonnull__))
   915 static inline void cx_map_remove_cxstr(
   916         CxMap *map,
   917         cxstring key
   918 ) {
   919     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   920 }
   922 /**
   923  * Removes a key/value-pair from the map by using the key.
   924  *
   925  * @param map the map
   926  * @param key the key
   927  */
   928 __attribute__((__nonnull__))
   929 static inline void cx_map_remove_mustr(
   930         CxMap *map,
   931         cxmutstr key
   932 ) {
   933     (void) map->cl->remove(map, cx_hash_key_cxstr(key), true);
   934 }
   936 /**
   937  * Removes a key/value-pair from the map by using the key.
   938  *
   939  * @param map the map
   940  * @param key the key
   941  */
   942 __attribute__((__nonnull__))
   943 static inline void cx_map_remove_str(
   944         CxMap *map,
   945         char const *key
   946 ) {
   947     (void) map->cl->remove(map, cx_hash_key_str(key), true);
   948 }
   950 /**
   951  * Removes a key/value-pair from the map by using the key.
   952  *
   953  * Always invokes the destructor function, if any, on the removed element.
   954  * If this map is storing pointers and you just want to retrieve the pointer
   955  * without invoking the destructor, use cxMapRemoveAndGet().
   956  * If you just want to detach the element from the map without invoking the
   957  * destructor or returning the element, use cxMapDetach().
   958  *
   959  * @param map the map
   960  * @param key the key
   961  * @see cxMapRemoveAndGet()
   962  * @see cxMapDetach()
   963  */
   964 #define cxMapRemove(map, key) _Generic((key), \
   965     CxHashKey: cx_map_remove,                 \
   966     cxstring: cx_map_remove_cxstr,            \
   967     cxmutstr: cx_map_remove_mustr,            \
   968     char*: cx_map_remove_str,                 \
   969     char const*: cx_map_remove_str)           \
   970     (map, key)
   972 /**
   973  * Detaches a key/value-pair from the map by using the key
   974  * without invoking the destructor.
   975  *
   976  * @param map the map
   977  * @param key the key
   978  */
   979 __attribute__((__nonnull__))
   980 static inline void cx_map_detach(
   981         CxMap *map,
   982         CxHashKey key
   983 ) {
   984     (void) map->cl->remove(map, key, false);
   985 }
   987 /**
   988  * Detaches a key/value-pair from the map by using the key
   989  * without invoking the destructor.
   990  *
   991  * @param map the map
   992  * @param key the key
   993  */
   994 __attribute__((__nonnull__))
   995 static inline void cx_map_detach_cxstr(
   996         CxMap *map,
   997         cxstring key
   998 ) {
   999     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
  1002 /**
  1003  * Detaches a key/value-pair from the map by using the key
  1004  * without invoking the destructor.
  1006  * @param map the map
  1007  * @param key the key
  1008  */
  1009 __attribute__((__nonnull__))
  1010 static inline void cx_map_detach_mustr(
  1011         CxMap *map,
  1012         cxmutstr key
  1013 ) {
  1014     (void) map->cl->remove(map, cx_hash_key_cxstr(key), false);
  1017 /**
  1018  * Detaches a key/value-pair from the map by using the key
  1019  * without invoking the destructor.
  1021  * @param map the map
  1022  * @param key the key
  1023  */
  1024 __attribute__((__nonnull__))
  1025 static inline void cx_map_detach_str(
  1026         CxMap *map,
  1027         char const *key
  1028 ) {
  1029     (void) map->cl->remove(map, cx_hash_key_str(key), false);
  1032 /**
  1033  * Detaches a key/value-pair from the map by using the key
  1034  * without invoking the destructor.
  1036  * In general, you should only use this function if the map does not own
  1037  * the data and there is a valid reference to the data somewhere else
  1038  * in the program. In all other cases it is preferable to use
  1039  * cxMapRemove() or cxMapRemoveAndGet().
  1041  * @param map the map
  1042  * @param key the key
  1043  * @see cxMapRemove()
  1044  * @see cxMapRemoveAndGet()
  1045  */
  1046 #define cxMapDetach(map, key) _Generic((key), \
  1047     CxHashKey: cx_map_detach,                 \
  1048     cxstring: cx_map_detach_cxstr,            \
  1049     cxmutstr: cx_map_detach_mustr,            \
  1050     char*: cx_map_detach_str,                 \
  1051     char const*: cx_map_detach_str)           \
  1052     (map, key)
  1054 /**
  1055  * Removes a key/value-pair from the map by using the key.
  1057  * @param map the map
  1058  * @param key the key
  1059  * @return the stored pointer or \c NULL if either the key is not present
  1060  * in the map or the map is not storing pointers
  1061  */
  1062 __attribute__((__nonnull__, __warn_unused_result__))
  1063 static inline void *cx_map_remove_and_get(
  1064         CxMap *map,
  1065         CxHashKey key
  1066 ) {
  1067     return map->cl->remove(map, key, !map->store_pointer);
  1070 /**
  1071  * Removes a key/value-pair from the map by using the key.
  1073  * @param map the map
  1074  * @param key the key
  1075  * @return the stored pointer or \c NULL if either the key is not present
  1076  * in the map or the map is not storing pointers
  1077  */
  1078 __attribute__((__nonnull__, __warn_unused_result__))
  1079 static inline void *cx_map_remove_and_get_cxstr(
  1080         CxMap *map,
  1081         cxstring key
  1082 ) {
  1083     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
  1086 /**
  1087  * Removes a key/value-pair from the map by using the key.
  1089  * @param map the map
  1090  * @param key the key
  1091  * @return the stored pointer or \c NULL if either the key is not present
  1092  * in the map or the map is not storing pointers
  1093  */
  1094 __attribute__((__nonnull__, __warn_unused_result__))
  1095 static inline void *cx_map_remove_and_get_mustr(
  1096         CxMap *map,
  1097         cxmutstr key
  1098 ) {
  1099     return map->cl->remove(map, cx_hash_key_cxstr(key), !map->store_pointer);
  1102 /**
  1103  * Removes a key/value-pair from the map by using the key.
  1105  * @param map the map
  1106  * @param key the key
  1107  * @return the stored pointer or \c NULL if either the key is not present
  1108  * in the map or the map is not storing pointers
  1109  */
  1110 __attribute__((__nonnull__, __warn_unused_result__))
  1111 static inline void *cx_map_remove_and_get_str(
  1112         CxMap *map,
  1113         char const *key
  1114 ) {
  1115     return map->cl->remove(map, cx_hash_key_str(key), !map->store_pointer);
  1118 /**
  1119  * Removes a key/value-pair from the map by using the key.
  1121  * This function can be used when the map is storing pointers,
  1122  * in order to retrieve the pointer from the map without invoking
  1123  * any destructor function. Sometimes you do not want the pointer
  1124  * to be returned - in that case (instead of suppressing the "unused
  1125  * result" warning) you can use cxMapDetach().
  1127  * If this map is not storing pointers, this function behaves like
  1128  * cxMapRemove() and returns \c NULL.
  1130  * @param map the map
  1131  * @param key the key
  1132  * @return the stored pointer or \c NULL if either the key is not present
  1133  * in the map or the map is not storing pointers
  1134  * @see cxMapStorePointers()
  1135  * @see cxMapDetach()
  1136  */
  1137 #define cxMapRemoveAndGet(map, key) _Generic((key), \
  1138     CxHashKey: cx_map_remove_and_get,               \
  1139     cxstring: cx_map_remove_and_get_cxstr,          \
  1140     cxmutstr: cx_map_remove_and_get_mustr,          \
  1141     char*: cx_map_remove_and_get_str,               \
  1142     char const*: cx_map_remove_and_get_str)         \
  1143     (map, key)
  1145 #endif // __cplusplus
  1147 #endif // UCX_MAP_H

mercurial