src/cx/map.h

Sun, 21 May 2023 16:22:09 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 21 May 2023 16:22:09 +0200
changeset 710
2dd409ed056f
parent 709
1e8ba59e7911
child 714
34565d898f1f
permissions
-rw-r--r--

fix const-ness of non-mutating iterator creation for maps

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

mercurial