]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
c2f1db8f | 2 | #pragma once |
60918275 | 3 | |
a7334b09 LP |
4 | /*** |
5 | This file is part of systemd. | |
6 | ||
7 | Copyright 2010 Lennart Poettering | |
89439d4f | 8 | Copyright 2014 Michal Schmidt |
a7334b09 LP |
9 | |
10 | systemd is free software; you can redistribute it and/or modify it | |
5430f7f2 LP |
11 | under the terms of the GNU Lesser General Public License as published by |
12 | the Free Software Foundation; either version 2.1 of the License, or | |
a7334b09 LP |
13 | (at your option) any later version. |
14 | ||
15 | systemd is distributed in the hope that it will be useful, but | |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
5430f7f2 | 18 | Lesser General Public License for more details. |
a7334b09 | 19 | |
5430f7f2 | 20 | You should have received a copy of the GNU Lesser General Public License |
a7334b09 LP |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. |
22 | ***/ | |
23 | ||
11c3a366 | 24 | #include <limits.h> |
60918275 | 25 | #include <stdbool.h> |
11c3a366 | 26 | #include <stddef.h> |
60918275 | 27 | |
758dd67e | 28 | #include "hash-funcs.h" |
44a6b1b6 | 29 | #include "macro.h" |
5e2f14e6 | 30 | #include "util.h" |
44a6b1b6 | 31 | |
89439d4f MS |
32 | /* |
33 | * A hash table implementation. As a minor optimization a NULL hashmap object | |
34 | * will be treated as empty hashmap for all read operations. That way it is not | |
35 | * necessary to instantiate an object for each Hashmap use. | |
36 | * | |
fc86aa0e | 37 | * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap), |
89439d4f MS |
38 | * the implemention will: |
39 | * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py) | |
40 | * - perform extra checks for invalid use of iterators | |
41 | */ | |
60918275 | 42 | |
9bf3b535 LP |
43 | #define HASH_KEY_SIZE 16 |
44 | ||
89439d4f MS |
45 | /* The base type for all hashmap and set types. Many functions in the |
46 | * implementation take (HashmapBase*) parameters and are run-time polymorphic, | |
47 | * though the API is not meant to be polymorphic (do not call functions | |
90df619e | 48 | * internal_*() directly). */ |
89439d4f MS |
49 | typedef struct HashmapBase HashmapBase; |
50 | ||
51 | /* Specific hashmap/set types */ | |
52 | typedef struct Hashmap Hashmap; /* Maps keys to values */ | |
53 | typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */ | |
54 | typedef struct Set Set; /* Stores just keys */ | |
55 | ||
56 | /* Ideally the Iterator would be an opaque struct, but it is instantiated | |
57 | * by hashmap users, so the definition has to be here. Do not use its fields | |
58 | * directly. */ | |
59 | typedef struct { | |
60 | unsigned idx; /* index of an entry to be iterated next */ | |
61 | const void *next_key; /* expected value of that entry's key pointer */ | |
349cc4a5 | 62 | #if ENABLE_DEBUG_HASHMAP |
89439d4f MS |
63 | unsigned put_count; /* hashmap's put_count recorded at start of iteration */ |
64 | unsigned rem_count; /* hashmap's rem_count in previous iteration */ | |
65 | unsigned prev_idx; /* idx in previous iteration */ | |
66 | #endif | |
67 | } Iterator; | |
034c6ed7 | 68 | |
89439d4f MS |
69 | #define _IDX_ITERATOR_FIRST (UINT_MAX - 1) |
70 | #define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL }) | |
60918275 | 71 | |
89439d4f MS |
72 | /* Macros for type checking */ |
73 | #define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \ | |
74 | (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \ | |
75 | __builtin_types_compatible_p(typeof(h), Hashmap*) || \ | |
76 | __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \ | |
77 | __builtin_types_compatible_p(typeof(h), Set*)) | |
78 | ||
79 | #define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \ | |
80 | (__builtin_types_compatible_p(typeof(h), Hashmap*) || \ | |
81 | __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \ | |
82 | ||
83 | #define HASHMAP_BASE(h) \ | |
84 | __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \ | |
85 | (HashmapBase*)(h), \ | |
86 | (void)0) | |
87 | ||
88 | #define PLAIN_HASHMAP(h) \ | |
89 | __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \ | |
90 | (Hashmap*)(h), \ | |
91 | (void)0) | |
92 | ||
349cc4a5 | 93 | #if ENABLE_DEBUG_HASHMAP |
89439d4f MS |
94 | # define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line |
95 | # define HASHMAP_DEBUG_SRC_ARGS , __func__, __FILE__, __LINE__ | |
96 | # define HASHMAP_DEBUG_PASS_ARGS , func, file, line | |
97 | #else | |
98 | # define HASHMAP_DEBUG_PARAMS | |
99 | # define HASHMAP_DEBUG_SRC_ARGS | |
100 | # define HASHMAP_DEBUG_PASS_ARGS | |
101 | #endif | |
102 | ||
103 | Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); | |
104 | OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); | |
105 | #define hashmap_new(ops) internal_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) | |
106 | #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) | |
107 | ||
cfe561a4 DH |
108 | HashmapBase *internal_hashmap_free(HashmapBase *h); |
109 | static inline Hashmap *hashmap_free(Hashmap *h) { | |
110 | return (void*)internal_hashmap_free(HASHMAP_BASE(h)); | |
5ba43716 | 111 | } |
cfe561a4 DH |
112 | static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) { |
113 | return (void*)internal_hashmap_free(HASHMAP_BASE(h)); | |
89439d4f MS |
114 | } |
115 | ||
cfe561a4 DH |
116 | HashmapBase *internal_hashmap_free_free(HashmapBase *h); |
117 | static inline Hashmap *hashmap_free_free(Hashmap *h) { | |
118 | return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); | |
5ba43716 | 119 | } |
cfe561a4 DH |
120 | static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) { |
121 | return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); | |
5ba43716 | 122 | } |
89439d4f | 123 | |
cfe561a4 DH |
124 | Hashmap *hashmap_free_free_free(Hashmap *h); |
125 | static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) { | |
126 | return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h)); | |
5ba43716 | 127 | } |
89439d4f MS |
128 | |
129 | HashmapBase *internal_hashmap_copy(HashmapBase *h); | |
130 | static inline Hashmap *hashmap_copy(Hashmap *h) { | |
131 | return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h)); | |
5ba43716 | 132 | } |
89439d4f MS |
133 | static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) { |
134 | return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h)); | |
5ba43716 | 135 | } |
60918275 | 136 | |
89439d4f MS |
137 | int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); |
138 | int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); | |
139 | #define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) | |
140 | #define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) | |
141 | ||
60918275 | 142 | int hashmap_put(Hashmap *h, const void *key, void *value); |
5ba43716 | 143 | static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) { |
89439d4f | 144 | return hashmap_put(PLAIN_HASHMAP(h), key, value); |
5ba43716 | 145 | } |
89439d4f | 146 | |
d99ae53a | 147 | int hashmap_update(Hashmap *h, const void *key, void *value); |
5ba43716 | 148 | static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) { |
89439d4f | 149 | return hashmap_update(PLAIN_HASHMAP(h), key, value); |
5ba43716 | 150 | } |
89439d4f | 151 | |
3158713e | 152 | int hashmap_replace(Hashmap *h, const void *key, void *value); |
5ba43716 | 153 | static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) { |
89439d4f MS |
154 | return hashmap_replace(PLAIN_HASHMAP(h), key, value); |
155 | } | |
156 | ||
157 | void *internal_hashmap_get(HashmapBase *h, const void *key); | |
158 | static inline void *hashmap_get(Hashmap *h, const void *key) { | |
159 | return internal_hashmap_get(HASHMAP_BASE(h), key); | |
5ba43716 | 160 | } |
5ba43716 | 161 | static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) { |
89439d4f | 162 | return internal_hashmap_get(HASHMAP_BASE(h), key); |
5ba43716 | 163 | } |
89439d4f | 164 | |
2f79c10e | 165 | void *hashmap_get2(Hashmap *h, const void *key, void **rkey); |
5ba43716 | 166 | static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) { |
89439d4f MS |
167 | return hashmap_get2(PLAIN_HASHMAP(h), key, rkey); |
168 | } | |
169 | ||
170 | bool internal_hashmap_contains(HashmapBase *h, const void *key); | |
171 | static inline bool hashmap_contains(Hashmap *h, const void *key) { | |
172 | return internal_hashmap_contains(HASHMAP_BASE(h), key); | |
5ba43716 | 173 | } |
5ba43716 | 174 | static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) { |
89439d4f MS |
175 | return internal_hashmap_contains(HASHMAP_BASE(h), key); |
176 | } | |
177 | ||
178 | void *internal_hashmap_remove(HashmapBase *h, const void *key); | |
179 | static inline void *hashmap_remove(Hashmap *h, const void *key) { | |
180 | return internal_hashmap_remove(HASHMAP_BASE(h), key); | |
5ba43716 | 181 | } |
5ba43716 | 182 | static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) { |
89439d4f | 183 | return internal_hashmap_remove(HASHMAP_BASE(h), key); |
5ba43716 | 184 | } |
89439d4f | 185 | |
c582a3b3 | 186 | void *hashmap_remove2(Hashmap *h, const void *key, void **rkey); |
5ba43716 | 187 | static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) { |
89439d4f | 188 | return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey); |
5ba43716 | 189 | } |
89439d4f | 190 | |
2f79c10e | 191 | void *hashmap_remove_value(Hashmap *h, const void *key, void *value); |
5ba43716 | 192 | static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) { |
89439d4f | 193 | return hashmap_remove_value(PLAIN_HASHMAP(h), key, value); |
5ba43716 | 194 | } |
89439d4f | 195 | |
101d8e63 | 196 | int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); |
5ba43716 | 197 | static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { |
89439d4f | 198 | return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value); |
5ba43716 | 199 | } |
89439d4f | 200 | |
8fe914ec | 201 | int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); |
5ba43716 | 202 | static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { |
89439d4f | 203 | return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value); |
5ba43716 | 204 | } |
60918275 | 205 | |
89439d4f MS |
206 | /* Since merging data from a OrderedHashmap into a Hashmap or vice-versa |
207 | * should just work, allow this by having looser type-checking here. */ | |
208 | int internal_hashmap_merge(Hashmap *h, Hashmap *other); | |
209 | #define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other)) | |
210 | #define ordered_hashmap_merge(h, other) hashmap_merge(h, other) | |
211 | ||
212 | int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add); | |
213 | static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) { | |
214 | return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add); | |
5ba43716 | 215 | } |
e4c691b5 | 216 | static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) { |
89439d4f MS |
217 | return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add); |
218 | } | |
219 | ||
220 | int internal_hashmap_move(HashmapBase *h, HashmapBase *other); | |
221 | /* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */ | |
222 | static inline int hashmap_move(Hashmap *h, Hashmap *other) { | |
223 | return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); | |
e4c691b5 | 224 | } |
7ad63f57 | 225 | static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) { |
89439d4f MS |
226 | return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); |
227 | } | |
228 | ||
229 | int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key); | |
230 | static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { | |
231 | return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); | |
5ba43716 | 232 | } |
5ba43716 | 233 | static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) { |
89439d4f | 234 | return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); |
5ba43716 | 235 | } |
91cdde8a | 236 | |
89439d4f MS |
237 | unsigned internal_hashmap_size(HashmapBase *h) _pure_; |
238 | static inline unsigned hashmap_size(Hashmap *h) { | |
239 | return internal_hashmap_size(HASHMAP_BASE(h)); | |
240 | } | |
5ba43716 | 241 | static inline unsigned ordered_hashmap_size(OrderedHashmap *h) { |
89439d4f MS |
242 | return internal_hashmap_size(HASHMAP_BASE(h)); |
243 | } | |
244 | ||
245 | static inline bool hashmap_isempty(Hashmap *h) { | |
246 | return hashmap_size(h) == 0; | |
5ba43716 | 247 | } |
5ba43716 | 248 | static inline bool ordered_hashmap_isempty(OrderedHashmap *h) { |
89439d4f MS |
249 | return ordered_hashmap_size(h) == 0; |
250 | } | |
251 | ||
252 | unsigned internal_hashmap_buckets(HashmapBase *h) _pure_; | |
253 | static inline unsigned hashmap_buckets(Hashmap *h) { | |
254 | return internal_hashmap_buckets(HASHMAP_BASE(h)); | |
5ba43716 | 255 | } |
5ba43716 | 256 | static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) { |
89439d4f | 257 | return internal_hashmap_buckets(HASHMAP_BASE(h)); |
5ba43716 | 258 | } |
60918275 | 259 | |
8927b1da DH |
260 | bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key); |
261 | static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) { | |
262 | return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); | |
89439d4f | 263 | } |
8927b1da DH |
264 | static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) { |
265 | return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); | |
5ba43716 | 266 | } |
60918275 | 267 | |
89439d4f MS |
268 | void internal_hashmap_clear(HashmapBase *h); |
269 | static inline void hashmap_clear(Hashmap *h) { | |
270 | internal_hashmap_clear(HASHMAP_BASE(h)); | |
271 | } | |
5ba43716 | 272 | static inline void ordered_hashmap_clear(OrderedHashmap *h) { |
89439d4f MS |
273 | internal_hashmap_clear(HASHMAP_BASE(h)); |
274 | } | |
275 | ||
276 | void internal_hashmap_clear_free(HashmapBase *h); | |
277 | static inline void hashmap_clear_free(Hashmap *h) { | |
278 | internal_hashmap_clear_free(HASHMAP_BASE(h)); | |
5ba43716 | 279 | } |
5ba43716 | 280 | static inline void ordered_hashmap_clear_free(OrderedHashmap *h) { |
89439d4f | 281 | internal_hashmap_clear_free(HASHMAP_BASE(h)); |
5ba43716 | 282 | } |
89439d4f | 283 | |
fabe5c0e | 284 | void hashmap_clear_free_free(Hashmap *h); |
5ba43716 | 285 | static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { |
89439d4f | 286 | hashmap_clear_free_free(PLAIN_HASHMAP(h)); |
5ba43716 | 287 | } |
9946996c | 288 | |
89439d4f MS |
289 | /* |
290 | * Note about all *_first*() functions | |
291 | * | |
292 | * For plain Hashmaps and Sets the order of entries is undefined. | |
293 | * The functions find whatever entry is first in the implementation | |
294 | * internal order. | |
295 | * | |
296 | * Only for OrderedHashmaps the order is well defined and finding | |
297 | * the first entry is O(1). | |
298 | */ | |
299 | ||
300 | void *internal_hashmap_steal_first(HashmapBase *h); | |
301 | static inline void *hashmap_steal_first(Hashmap *h) { | |
302 | return internal_hashmap_steal_first(HASHMAP_BASE(h)); | |
303 | } | |
5ba43716 | 304 | static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) { |
89439d4f MS |
305 | return internal_hashmap_steal_first(HASHMAP_BASE(h)); |
306 | } | |
307 | ||
308 | void *internal_hashmap_steal_first_key(HashmapBase *h); | |
309 | static inline void *hashmap_steal_first_key(Hashmap *h) { | |
310 | return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); | |
5ba43716 | 311 | } |
5ba43716 | 312 | static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) { |
89439d4f | 313 | return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); |
5ba43716 | 314 | } |
89439d4f MS |
315 | |
316 | void *internal_hashmap_first_key(HashmapBase *h) _pure_; | |
317 | static inline void *hashmap_first_key(Hashmap *h) { | |
318 | return internal_hashmap_first_key(HASHMAP_BASE(h)); | |
5ba43716 | 319 | } |
5ba43716 | 320 | static inline void *ordered_hashmap_first_key(OrderedHashmap *h) { |
89439d4f | 321 | return internal_hashmap_first_key(HASHMAP_BASE(h)); |
5ba43716 | 322 | } |
60918275 | 323 | |
89439d4f MS |
324 | void *internal_hashmap_first(HashmapBase *h) _pure_; |
325 | static inline void *hashmap_first(Hashmap *h) { | |
326 | return internal_hashmap_first(HASHMAP_BASE(h)); | |
5ba43716 | 327 | } |
89439d4f MS |
328 | static inline void *ordered_hashmap_first(OrderedHashmap *h) { |
329 | return internal_hashmap_first(HASHMAP_BASE(h)); | |
330 | } | |
331 | ||
332 | /* no hashmap_next */ | |
333 | void *ordered_hashmap_next(OrderedHashmap *h, const void *key); | |
3c1668da | 334 | |
89439d4f MS |
335 | char **internal_hashmap_get_strv(HashmapBase *h); |
336 | static inline char **hashmap_get_strv(Hashmap *h) { | |
337 | return internal_hashmap_get_strv(HASHMAP_BASE(h)); | |
338 | } | |
5ba43716 | 339 | static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) { |
89439d4f | 340 | return internal_hashmap_get_strv(HASHMAP_BASE(h)); |
5ba43716 | 341 | } |
db1413d7 | 342 | |
89439d4f MS |
343 | /* |
344 | * Hashmaps are iterated in unpredictable order. | |
345 | * OrderedHashmaps are an exception to this. They are iterated in the order | |
346 | * the entries were inserted. | |
347 | * It is safe to remove the current entry. | |
348 | */ | |
034c6ed7 | 349 | #define HASHMAP_FOREACH(e, h, i) \ |
8927b1da | 350 | for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); ) |
60918275 | 351 | |
5ba43716 | 352 | #define ORDERED_HASHMAP_FOREACH(e, h, i) \ |
8927b1da | 353 | for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); ) |
5ba43716 | 354 | |
034c6ed7 | 355 | #define HASHMAP_FOREACH_KEY(e, k, h, i) \ |
8927b1da | 356 | for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); ) |
11dd41ce | 357 | |
5ba43716 | 358 | #define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \ |
8927b1da | 359 | for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); ) |
5ba43716 | 360 | |
5e2f14e6 LP |
361 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free); |
362 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free); | |
363 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free); | |
5ba43716 MS |
364 | DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free); |
365 | DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free); | |
366 | DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free); | |
89439d4f | 367 | |
5e2f14e6 LP |
368 | #define _cleanup_hashmap_free_ _cleanup_(hashmap_freep) |
369 | #define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep) | |
370 | #define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep) | |
5ba43716 MS |
371 | #define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep) |
372 | #define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep) | |
373 | #define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep) |