src/cx/map.h

Tue, 20 Jun 2023 18:30:13 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 20 Jun 2023 18:30:13 +0200
changeset 714
34565d898f1f
parent 710
2dd409ed056f
child 759
475335643af4
permissions
-rw-r--r--

add missing docs for cxEmptyMap

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

mercurial