src/cx/map.h

Mon, 18 Dec 2023 14:14:47 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 18 Dec 2023 14:14:47 +0100
changeset 759
475335643af4
parent 714
34565d898f1f
permissions
-rw-r--r--

increase version number to 3.1

remove per-file version information
from Doxygen output

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

mercurial