src/cx/map.h

Thu, 23 May 2024 20:43:04 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 May 2024 20:43:04 +0200
changeset 856
6bbbf219251d
parent 855
35bcb3216c0d
child 857
4d12e34bb130
permissions
-rw-r--r--

fix name of collection base member (to avoid base.base)

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    28 /**
    29  * \file map.h
    30  * \brief Interface for map implementations.
    31  * \author Mike Becker
    32  * \author Olaf Wintermann
    33  * \copyright 2-Clause BSD License
    34  */
    36 #ifndef UCX_MAP_H
    37 #define UCX_MAP_H
    39 #include "common.h"
    40 #include "collection.h"
    41 #include "string.h"
    42 #include "hash_key.h"
    44 #ifdef    __cplusplus
    45 extern "C" {
    46 #endif
    48 /** Type for the UCX map. */
    49 typedef struct cx_map_s CxMap;
    51 /** Type for a map entry. */
    52 typedef struct cx_map_entry_s CxMapEntry;
    54 /** Type for map class definitions. */
    55 typedef struct cx_map_class_s cx_map_class;
    57 /** Structure for the UCX map. */
    58 struct cx_map_s {
    59     /**
    60      * Base attributes.
    61      */
    62     CX_COLLECTION_BASE;
    63     /** The map class definition. */
    64     cx_map_class *cl;
    65 };
    67 /**
    68  * The type of iterator for a map.
    69  */
    70 enum cx_map_iterator_type {
    71     /**
    72      * Iterates over key/value pairs.
    73      */
    74     CX_MAP_ITERATOR_PAIRS,
    75     /**
    76      * Iterates over keys only.
    77      */
    78     CX_MAP_ITERATOR_KEYS,
    79     /**
    80      * Iterates over values only.
    81      */
    82     CX_MAP_ITERATOR_VALUES
    83 };
    85 /**
    86  * The class definition for arbitrary maps.
    87  */
    88 struct cx_map_class_s {
    89     /**
    90      * Deallocates the entire memory.
    91      */
    92     __attribute__((__nonnull__))
    93     void (*destructor)(struct cx_map_s *map);
    95     /**
    96      * Removes all elements.
    97      */
    98     __attribute__((__nonnull__))
    99     void (*clear)(struct cx_map_s *map);
   101     /**
   102      * Add or overwrite an element.
   103      */
   104     __attribute__((__nonnull__))
   105     int (*put)(
   106             CxMap *map,
   107             CxHashKey key,
   108             void *value
   109     );
   111     /**
   112      * Returns an element.
   113      */
   114     __attribute__((__nonnull__, __warn_unused_result__))
   115     void *(*get)(
   116             CxMap const *map,
   117             CxHashKey key
   118     );
   120     /**
   121      * Removes an element.
   122      */
   123     __attribute__((__nonnull__))
   124     void *(*remove)(
   125             CxMap *map,
   126             CxHashKey key,
   127             bool destroy
   128     );
   130     /**
   131      * Creates an iterator for this map.
   132      */
   133     __attribute__((__nonnull__, __warn_unused_result__))
   134     CxIterator (*iterator)(CxMap const *map, enum cx_map_iterator_type type);
   135 };
   137 /**
   138  * A map entry.
   139  */
   140 struct cx_map_entry_s {
   141     /**
   142      * A pointer to the key.
   143      */
   144     CxHashKey const *key;
   145     /**
   146      * A pointer to the value.
   147      */
   148     void *value;
   149 };
   151 /**
   152  * A shared instance of an empty map.
   153  *
   154  * Writing to that map is undefined.
   155  */
   156 extern CxMap *const cxEmptyMap;
   158 /**
   159  * Advises the map to store copies of the objects (default mode of operation).
   160  *
   161  * Retrieving objects from this map will yield pointers to the copies stored
   162  * within this list.
   163  *
   164  * @param map the map
   165  * @see cxMapStorePointers()
   166  */
   167 __attribute__((__nonnull__))
   168 static inline void cxMapStoreObjects(CxMap *map) {
   169     map->collection.store_pointer = false;
   170 }
   172 /**
   173  * Advises the map to only store pointers to the objects.
   174  *
   175  * Retrieving objects from this list will yield the original pointers stored.
   176  *
   177  * @note This function forcibly sets the element size to the size of a pointer.
   178  * Invoking this function on a non-empty map that already stores copies of
   179  * objects is undefined.
   180  *
   181  * @param map the map
   182  * @see cxMapStoreObjects()
   183  */
   184 __attribute__((__nonnull__))
   185 static inline void cxMapStorePointers(CxMap *map) {
   186     map->collection.store_pointer = true;
   187     map->collection.elem_size = sizeof(void *);
   188 }
   191 /**
   192  * Deallocates the memory of the specified map.
   193  *
   194  * @param map the map to be destroyed
   195  */
   196 __attribute__((__nonnull__))
   197 static inline void cxMapDestroy(CxMap *map) {
   198     map->cl->destructor(map);
   199 }
   202 /**
   203  * Clears a map by removing all elements.
   204  *
   205  * @param map the map to be cleared
   206  */
   207 __attribute__((__nonnull__))
   208 static inline void cxMapClear(CxMap *map) {
   209     map->cl->clear(map);
   210 }
   212 /**
   213  * Returns the number of elements in this map.
   214  *
   215  * @param map the map
   216  * @return the number of stored elements
   217  */
   218 __attribute__((__nonnull__))
   219 static inline size_t cxMapSize(CxMap const *map) {
   220     return map->collection.size;
   221 }
   224 // TODO: set-like map operations (union, intersect, difference)
   226 /**
   227  * Creates a value iterator for a map.
   228  *
   229  * \note An iterator iterates over all elements successively. Therefore the order
   230  * highly depends on the map implementation and may change arbitrarily when the contents change.
   231  *
   232  * @param map the map to create the iterator for
   233  * @return an iterator for the currently stored values
   234  */
   235 __attribute__((__nonnull__, __warn_unused_result__))
   236 static inline CxIterator cxMapIteratorValues(CxMap const *map) {
   237     return map->cl->iterator(map, CX_MAP_ITERATOR_VALUES);
   238 }
   240 /**
   241  * Creates a key iterator for a map.
   242  *
   243  * The elements of the iterator are keys of type CxHashKey.
   244  *
   245  * \note An iterator iterates over all elements successively. Therefore the order
   246  * highly depends on the map implementation and may change arbitrarily when the contents change.
   247  *
   248  * @param map the map to create the iterator for
   249  * @return an iterator for the currently stored keys
   250  */
   251 __attribute__((__nonnull__, __warn_unused_result__))
   252 static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
   253     return map->cl->iterator(map, CX_MAP_ITERATOR_KEYS);
   254 }
   256 /**
   257  * Creates an iterator for a map.
   258  *
   259  * The elements of the iterator are key/value pairs of type CxMapEntry.
   260  *
   261  * \note An iterator iterates over all elements successively. Therefore the order
   262  * highly depends on the map implementation and may change arbitrarily when the contents change.
   263  *
   264  * @param map the map to create the iterator for
   265  * @return an iterator for the currently stored entries
   266  * @see cxMapIteratorKeys()
   267  * @see cxMapIteratorValues()
   268  */
   269 __attribute__((__nonnull__, __warn_unused_result__))
   270 static inline CxIterator cxMapIterator(CxMap const *map) {
   271     return map->cl->iterator(map, CX_MAP_ITERATOR_PAIRS);
   272 }
   275 /**
   276  * Creates a mutating iterator over the values of a map.
   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 values
   283  */
   284 __attribute__((__nonnull__, __warn_unused_result__))
   285 CxIterator cxMapMutIteratorValues(CxMap *map);
   287 /**
   288  * Creates a mutating iterator over the keys of a map.
   289  *
   290  * The elements of the iterator are keys of type CxHashKey.
   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 keys
   297  */
   298 __attribute__((__nonnull__, __warn_unused_result__))
   299 CxIterator cxMapMutIteratorKeys(CxMap *map);
   301 /**
   302  * Creates a mutating iterator for a map.
   303  *
   304  * The elements of the iterator are key/value pairs of type CxMapEntry.
   305  *
   306  * \note An iterator iterates over all elements successively. Therefore the order
   307  * highly depends on the map implementation and may change arbitrarily when the contents change.
   308  *
   309  * @param map the map to create the iterator for
   310  * @return an iterator for the currently stored entries
   311  * @see cxMapMutIteratorKeys()
   312  * @see cxMapMutIteratorValues()
   313  */
   314 __attribute__((__nonnull__, __warn_unused_result__))
   315 CxIterator cxMapMutIterator(CxMap *map);
   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->collection.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->collection.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->collection.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->collection.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