LCOV - code coverage report
Current view: top level - basic - hashmap.h (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 129 134 96.3 %
Date: 2019-08-22 15:41:25 Functions: 63 65 96.9 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : #pragma once
       3             : 
       4             : #include <limits.h>
       5             : #include <stdbool.h>
       6             : #include <stddef.h>
       7             : 
       8             : #include "hash-funcs.h"
       9             : #include "macro.h"
      10             : #include "util.h"
      11             : 
      12             : /*
      13             :  * A hash table implementation. As a minor optimization a NULL hashmap object
      14             :  * will be treated as empty hashmap for all read operations. That way it is not
      15             :  * necessary to instantiate an object for each Hashmap use.
      16             :  *
      17             :  * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
      18             :  * the implementation will:
      19             :  * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
      20             :  * - perform extra checks for invalid use of iterators
      21             :  */
      22             : 
      23             : #define HASH_KEY_SIZE 16
      24             : 
      25             : typedef void* (*hashmap_destroy_t)(void *p);
      26             : 
      27             : /* The base type for all hashmap and set types. Many functions in the
      28             :  * implementation take (HashmapBase*) parameters and are run-time polymorphic,
      29             :  * though the API is not meant to be polymorphic (do not call functions
      30             :  * internal_*() directly). */
      31             : typedef struct HashmapBase HashmapBase;
      32             : 
      33             : /* Specific hashmap/set types */
      34             : typedef struct Hashmap Hashmap;               /* Maps keys to values */
      35             : typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */
      36             : typedef struct Set Set;                       /* Stores just keys */
      37             : 
      38             : typedef struct IteratedCache IteratedCache;   /* Caches the iterated order of one of the above */
      39             : 
      40             : /* Ideally the Iterator would be an opaque struct, but it is instantiated
      41             :  * by hashmap users, so the definition has to be here. Do not use its fields
      42             :  * directly. */
      43             : typedef struct {
      44             :         unsigned idx;         /* index of an entry to be iterated next */
      45             :         const void *next_key; /* expected value of that entry's key pointer */
      46             : #if ENABLE_DEBUG_HASHMAP
      47             :         unsigned put_count;   /* hashmap's put_count recorded at start of iteration */
      48             :         unsigned rem_count;   /* hashmap's rem_count in previous iteration */
      49             :         unsigned prev_idx;    /* idx in previous iteration */
      50             : #endif
      51             : } Iterator;
      52             : 
      53             : #define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
      54             : #define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
      55             : 
      56             : /* Macros for type checking */
      57             : #define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \
      58             :         (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \
      59             :          __builtin_types_compatible_p(typeof(h), Hashmap*) || \
      60             :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \
      61             :          __builtin_types_compatible_p(typeof(h), Set*))
      62             : 
      63             : #define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \
      64             :         (__builtin_types_compatible_p(typeof(h), Hashmap*) || \
      65             :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \
      66             : 
      67             : #define HASHMAP_BASE(h) \
      68             :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \
      69             :                 (HashmapBase*)(h), \
      70             :                 (void)0)
      71             : 
      72             : #define PLAIN_HASHMAP(h) \
      73             :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \
      74             :                 (Hashmap*)(h), \
      75             :                 (void)0)
      76             : 
      77             : #if ENABLE_DEBUG_HASHMAP
      78             : # define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
      79             : # define HASHMAP_DEBUG_SRC_ARGS   , __func__, PROJECT_FILE, __LINE__
      80             : # define HASHMAP_DEBUG_PASS_ARGS   , func, file, line
      81             : #else
      82             : # define HASHMAP_DEBUG_PARAMS
      83             : # define HASHMAP_DEBUG_SRC_ARGS
      84             : # define HASHMAP_DEBUG_PASS_ARGS
      85             : #endif
      86             : 
      87             : Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
      88             : OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
      89             : #define hashmap_new(ops) internal_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
      90             : #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
      91             : 
      92             : HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
      93       54202 : static inline Hashmap *hashmap_free(Hashmap *h) {
      94       54202 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
      95             : }
      96        2070 : static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
      97        2070 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
      98             : }
      99             : 
     100         330 : static inline Hashmap *hashmap_free_free(Hashmap *h) {
     101         330 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
     102             : }
     103        9998 : static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
     104        9998 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
     105             : }
     106             : 
     107          51 : static inline Hashmap *hashmap_free_free_key(Hashmap *h) {
     108          51 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
     109             : }
     110           0 : static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) {
     111           0 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
     112             : }
     113             : 
     114        8254 : static inline Hashmap *hashmap_free_free_free(Hashmap *h) {
     115        8254 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
     116             : }
     117       15914 : static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
     118       15914 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
     119             : }
     120             : 
     121             : IteratedCache *iterated_cache_free(IteratedCache *cache);
     122             : int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
     123             : 
     124             : HashmapBase *internal_hashmap_copy(HashmapBase *h);
     125           1 : static inline Hashmap *hashmap_copy(Hashmap *h) {
     126           1 :         return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     127             : }
     128           1 : static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
     129           1 :         return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     130             : }
     131             : 
     132             : int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     133             : int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     134             : #define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     135             : #define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     136             : 
     137             : IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h);
     138           1 : static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
     139           1 :         return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
     140             : }
     141         212 : static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
     142         212 :         return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
     143             : }
     144             : 
     145             : int hashmap_put(Hashmap *h, const void *key, void *value);
     146       12122 : static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
     147       12122 :         return hashmap_put(PLAIN_HASHMAP(h), key, value);
     148             : }
     149             : 
     150             : int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
     151             : 
     152             : int hashmap_update(Hashmap *h, const void *key, void *value);
     153           2 : static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
     154           2 :         return hashmap_update(PLAIN_HASHMAP(h), key, value);
     155             : }
     156             : 
     157             : int hashmap_replace(Hashmap *h, const void *key, void *value);
     158       57041 : static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
     159       57041 :         return hashmap_replace(PLAIN_HASHMAP(h), key, value);
     160             : }
     161             : 
     162             : void *internal_hashmap_get(HashmapBase *h, const void *key);
     163       68314 : static inline void *hashmap_get(Hashmap *h, const void *key) {
     164       68314 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     165             : }
     166       43637 : static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
     167       43637 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     168             : }
     169             : 
     170             : void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
     171       56982 : static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
     172       56982 :         return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
     173             : }
     174             : 
     175             : bool internal_hashmap_contains(HashmapBase *h, const void *key);
     176        4584 : static inline bool hashmap_contains(Hashmap *h, const void *key) {
     177        4584 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     178             : }
     179        1144 : static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
     180        1144 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     181             : }
     182             : 
     183             : void *internal_hashmap_remove(HashmapBase *h, const void *key);
     184       62739 : static inline void *hashmap_remove(Hashmap *h, const void *key) {
     185       62739 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     186             : }
     187         434 : static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
     188         434 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     189             : }
     190             : 
     191             : void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
     192         331 : static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
     193         331 :         return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
     194             : }
     195             : 
     196             : void *internal_hashmap_remove_value(HashmapBase *h, const void *key, void *value);
     197        3931 : static inline void *hashmap_remove_value(Hashmap *h, const void *key, void *value) {
     198        3931 :         return internal_hashmap_remove_value(HASHMAP_BASE(h), key, value);
     199             : }
     200             : 
     201           4 : static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
     202           4 :         return hashmap_remove_value(PLAIN_HASHMAP(h), key, value);
     203             : }
     204             : 
     205             : int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
     206           4 : static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     207           4 :         return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value);
     208             : }
     209             : 
     210             : int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
     211          24 : static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     212          24 :         return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value);
     213             : }
     214             : 
     215             : /* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
     216             :  * should just work, allow this by having looser type-checking here. */
     217             : int internal_hashmap_merge(Hashmap *h, Hashmap *other);
     218             : #define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
     219             : #define ordered_hashmap_merge(h, other) hashmap_merge(h, other)
     220             : 
     221             : int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
     222           4 : static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
     223           4 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     224             : }
     225           4 : static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
     226           4 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     227             : }
     228             : 
     229             : int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
     230             : /* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
     231           2 : static inline int hashmap_move(Hashmap *h, Hashmap *other) {
     232           2 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     233             : }
     234           2 : static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
     235           2 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     236             : }
     237             : 
     238             : int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
     239           5 : static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
     240           5 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     241             : }
     242          79 : static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
     243          79 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     244             : }
     245             : 
     246             : unsigned internal_hashmap_size(HashmapBase *h) _pure_;
     247       11282 : static inline unsigned hashmap_size(Hashmap *h) {
     248       11282 :         return internal_hashmap_size(HASHMAP_BASE(h));
     249             : }
     250       10376 : static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
     251       10376 :         return internal_hashmap_size(HASHMAP_BASE(h));
     252             : }
     253             : 
     254        8051 : static inline bool hashmap_isempty(Hashmap *h) {
     255        8051 :         return hashmap_size(h) == 0;
     256             : }
     257         440 : static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
     258         440 :         return ordered_hashmap_size(h) == 0;
     259             : }
     260             : 
     261             : unsigned internal_hashmap_buckets(HashmapBase *h) _pure_;
     262          10 : static inline unsigned hashmap_buckets(Hashmap *h) {
     263          10 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     264             : }
     265          10 : static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
     266          10 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     267             : }
     268             : 
     269             : bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
     270      619028 : static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
     271      619028 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     272             : }
     273       18837 : static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
     274       18837 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     275             : }
     276             : 
     277             : void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
     278          32 : static inline void hashmap_clear(Hashmap *h) {
     279          32 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
     280          32 : }
     281          24 : static inline void ordered_hashmap_clear(OrderedHashmap *h) {
     282          24 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
     283          24 : }
     284             : 
     285           2 : static inline void hashmap_clear_free(Hashmap *h) {
     286           2 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
     287           2 : }
     288           2 : static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
     289           2 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
     290           2 : }
     291             : 
     292             : static inline void hashmap_clear_free_key(Hashmap *h) {
     293             :         internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
     294             : }
     295           0 : static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) {
     296           0 :         internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
     297           0 : }
     298             : 
     299           2 : static inline void hashmap_clear_free_free(Hashmap *h) {
     300           2 :         internal_hashmap_clear(HASHMAP_BASE(h), free, free);
     301           2 : }
     302           2 : static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
     303           2 :         internal_hashmap_clear(HASHMAP_BASE(h), free, free);
     304           2 : }
     305             : 
     306             : /*
     307             :  * Note about all *_first*() functions
     308             :  *
     309             :  * For plain Hashmaps and Sets the order of entries is undefined.
     310             :  * The functions find whatever entry is first in the implementation
     311             :  * internal order.
     312             :  *
     313             :  * Only for OrderedHashmaps the order is well defined and finding
     314             :  * the first entry is O(1).
     315             :  */
     316             : 
     317             : void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key);
     318          72 : static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) {
     319          72 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
     320             : }
     321             : static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) {
     322             :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
     323             : }
     324             : static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) {
     325             :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
     326             : }
     327             : static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) {
     328             :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
     329             : }
     330             : 
     331         904 : static inline void *hashmap_steal_first(Hashmap *h) {
     332         904 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
     333             : }
     334       12727 : static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
     335       12727 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
     336             : }
     337        2991 : static inline void *hashmap_first(Hashmap *h) {
     338        2991 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
     339             : }
     340         120 : static inline void *ordered_hashmap_first(OrderedHashmap *h) {
     341         120 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
     342             : }
     343             : 
     344        4454 : static inline void *internal_hashmap_first_key(HashmapBase *h, bool remove) {
     345        4454 :         void *key = NULL;
     346             : 
     347        4454 :         (void) internal_hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key);
     348        4454 :         return key;
     349             : }
     350        3672 : static inline void *hashmap_steal_first_key(Hashmap *h) {
     351        3672 :         return internal_hashmap_first_key(HASHMAP_BASE(h), true);
     352             : }
     353           2 : static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
     354           2 :         return internal_hashmap_first_key(HASHMAP_BASE(h), true);
     355             : }
     356         396 : static inline void *hashmap_first_key(Hashmap *h) {
     357         396 :         return internal_hashmap_first_key(HASHMAP_BASE(h), false);
     358             : }
     359         384 : static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
     360         384 :         return internal_hashmap_first_key(HASHMAP_BASE(h), false);
     361             : }
     362             : 
     363             : #define hashmap_clear_with_destructor(_s, _f)                   \
     364             :         ({                                                      \
     365             :                 void *_item;                                    \
     366             :                 while ((_item = hashmap_steal_first(_s)))       \
     367             :                         _f(_item);                              \
     368             :         })
     369             : #define hashmap_free_with_destructor(_s, _f)                    \
     370             :         ({                                                      \
     371             :                 hashmap_clear_with_destructor(_s, _f);          \
     372             :                 hashmap_free(_s);                               \
     373             :         })
     374             : #define ordered_hashmap_clear_with_destructor(_s, _f)                   \
     375             :         ({                                                              \
     376             :                 void *_item;                                            \
     377             :                 while ((_item = ordered_hashmap_steal_first(_s)))       \
     378             :                         _f(_item);                                      \
     379             :         })
     380             : #define ordered_hashmap_free_with_destructor(_s, _f)                    \
     381             :         ({                                                              \
     382             :                 ordered_hashmap_clear_with_destructor(_s, _f);          \
     383             :                 ordered_hashmap_free(_s);                               \
     384             :         })
     385             : 
     386             : /* no hashmap_next */
     387             : void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
     388             : 
     389             : char **internal_hashmap_get_strv(HashmapBase *h);
     390         957 : static inline char **hashmap_get_strv(Hashmap *h) {
     391         957 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     392             : }
     393           1 : static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
     394           1 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     395             : }
     396             : 
     397             : /*
     398             :  * Hashmaps are iterated in unpredictable order.
     399             :  * OrderedHashmaps are an exception to this. They are iterated in the order
     400             :  * the entries were inserted.
     401             :  * It is safe to remove the current entry.
     402             :  */
     403             : #define HASHMAP_FOREACH(e, h, i) \
     404             :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     405             : 
     406             : #define ORDERED_HASHMAP_FOREACH(e, h, i) \
     407             :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     408             : 
     409             : #define HASHMAP_FOREACH_KEY(e, k, h, i) \
     410             :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     411             : 
     412             : #define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
     413             :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     414             : 
     415        5296 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
     416           1 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
     417             : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_key);
     418           9 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
     419         210 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
     420             : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
     421             : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_key);
     422           1 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
     423             : 
     424             : #define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
     425             : #define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
     426             : #define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
     427             : #define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep)
     428             : #define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep)
     429             : #define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep)
     430             : 
     431             : DEFINE_TRIVIAL_CLEANUP_FUNC(IteratedCache*, iterated_cache_free);
     432             : 
     433             : #define _cleanup_iterated_cache_free_ _cleanup_(iterated_cache_freep)

Generated by: LCOV version 1.14