Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / utility / spechash.h
blob7706f721ed0ac361f5d139bb558cce5f66140dea
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 /* spechashs: "specific genhash".
16 * This file is used to implement a "specific" genhash.
17 * That is, a (sometimes) type-checked genhash. (Or at least a
18 * genhash with related functions with distinctly typed parameters.)
20 * Before including this file, you must define the following:
21 * SPECHASH_TAG - this tag will be used to form names for functions etc.
22 * SPECHASH_IKEY_TYPE - the typed genhash will use this type as key.
23 * (genhash internal usage). You may omit this setting defining
24 * SPECHASH_INT_KEY_TYPE, SPECHASH_ENUM_KEY_TYPE,
25 * SPECHASH_ASTR_KEY_TYPE, or SPECHASH_CSTR_KEY_TYPE, by convenience
26 * for integer, enumerators, or strings.
27 * SPECHASH_IDATA_TYPE - the typed genhash will use this type as data.
28 * (genhash internal usage). You may omit this setting defining
29 * SPECHASH_INT_DATA_TYPE, SPECHASH_ENUM_DATA_TYPE,
30 * SPECHASH_ASTR_DATA_TYPE, or SPECHASH_CSTR_DATA_TYPE, by convenience
31 * for integers, enumerators, or strings.
32 * You may also define:
33 * SPECHASH_UKEY_TYPE - the typed genhash will use this as key.
34 * (external user usage, see SPECHASH_UKEY_TO_IKEY and
35 * SPECHASH_IKEY_TO_UKEY convertors).
36 * SPECHASH_UDATA_TYPE - the typed genhash will use this type as data.
37 * (external user usage, see SPECHASH_IDATA_TO_UDATA and
38 * SPECHASH_UDATA_TO_IDATA convertos).
39 * SPECHASH_IKEY_VAL - The default hash function.
40 * SPECHASH_IKEY_COMP - The default hash key comparator function.
41 * SPECHASH_IKEY_COPY - The default key copy function.
42 * SPECHASH_IKEY_FREE - The default key free function.
43 * SPECHASH_IDATA_COMP - The default data comparator function.
44 * SPECHASH_IDATA_COPY - The default data copy function.
45 * SPECHASH_IDATA_FREE - The default data free function.
46 * SPECHASH_UKEY_TO_IKEY - A function or macro to convert a key to
47 * pointer.
48 * SPECHASH_IKEY_TO_UKEY - A function or macro to convert a pointer to
49 * key.
50 * SPECHASH_IDATA_TO_UDATA - A function or macro to convert a data to
51 * pointer.
52 * SPECHASH_UDATA_TO_IDATA - A function or macro to convert a pointer
53 * to data.
54 * At the end of this file, these (and other defines) are undef-ed.
56 * Assuming SPECHASH_TAG were 'foo', SPECHASH_IKEY_TYPE were 'key_t', and
57 * SPECHASH_IDATA_TYPE were 'data_t'.
58 * including this file would provide a struct definition for:
59 * struct foo_hash;
60 * struct foo_hash_iter;
62 * function typedefs:
63 * typedef genhash_val_t (*foo_hash_key_val_fn_t) (const key_t);
64 * typedef bool (*foo_hash_key_comp_fn_t) (const key_t, const key_t);
65 * typedef key_t (*foo_hash_key_copy_fn_t) (const key_t);
66 * typedef void (*foo_hash_key_free_fn_t) (key_t);
67 * typedef bool (*foo_hash_data_comp_fn_t) (const data_t, const data_t);
68 * typedef data_t (*foo_hash_data_copy_fn_t) (const data_t);
69 * typedef void (*foo_hash_data_free_fn_t) (data_t);
71 * and prototypes for the following functions:
72 * struct foo_hash *foo_hash_new(void);
73 * struct foo_hash *foo_hash_new_full(foo_hash_key_val_fn_t key_val,
74 * foo_hash_key_comp_fn_t key_comp,
75 * foo_hash_key_copy_fn_t key_copy,
76 * foo_hash_key_free_fn_t key_free,
77 * foo_hash_data_copy_fn_t data_val,
78 * foo_hash_data_free_fn_t data_free);
79 * struct foo_hash *foo_hash_new_nentries(size_t nentries);
80 * struct foo_hash *
81 * foo_hash_new_nentries_full(foo_hash_key_val_fn_t key_val,
82 * foo_hash_key_comp_fn_t key_comp,
83 * foo_hash_key_copy_fn_t key_copy,
84 * foo_hash_key_free_fn_t key_free,
85 * foo_hash_data_copy_fn_t data_val,
86 * foo_hash_data_free_fn_t data_free,
87 * size_t nentries);
88 * void foo_hash_destroy(struct foo_hash *phash);
89 * bool foo_hash_set_no_shrink(struct foo_hash *phash, bool no_shrink);
90 * size_t foo_hash_size(const struct foo_hash *phash);
91 * size_t foo_hash_capacity(const struct foo_hash *phash);
92 * struct foo_hash *foo_hash_copy(const struct foo_hash *phash);
93 * void foo_hash_clear(struct foo_hash *phash);
94 * bool foo_hash_insert(struct foo_hash *phash, const key_t key,
95 * const data_t data);
96 * bool foo_hash_replace(struct foo_hash *phash, const key_t key,
97 * const data_t data);
98 * bool foo_hash_replace_full(struct foo_hash *phash, const key_t key,
99 * const data_t data, key_t *old_pkey,
100 * data_t *old_pdata);
101 * bool foo_hash_lookup(const struct foo_hash *phash, const key_t key,
102 * data_t *pdata);
103 * bool foo_hash_remove(struct foo_hash *phash, const key_t key);
104 * bool foo_hash_remove_full(struct foo_hash *phash, const key_t key,
105 * key_t *deleted_pkey, data_t *deleted_pdata);
107 * bool foo_hashs_are_equal(const struct foo_hash *phash1,
108 * const struct foo_hash *phash2);
109 * bool foo_hashs_are_equal_full(const struct foo_hash *phash1,
110 * const struct foo_hash *phash2,
111 * foo_hash_data_comp_fn_t data_comp_func);
113 * size_t foo_hash_iter_sizeof(void);
114 * struct iterator *foo_hash_iter_init(struct foo_hash_iter *iter,
115 * const struct foo_hash *phash);
116 * struct iterator *foo_hash_key_iter_init(struct foo_hash_iter *iter,
117 * const struct foo_hash *phash);
118 * struct iterator *foo_hash_value_init(struct foo_hash_iter *iter,
119 * const struct foo_hash *phash);
121 * You should also define yourself (this file cannot do this for you):
122 * #define foo_hash_data_iterate(phash, data) \
123 * TYPED_HASH_DATA_ITERATE(data_t, phash, data)
124 * #define foo_hash_data_iterate_end HASH_DATA_ITERATE_END
126 * #define foo_hash_keys_iterate(phash, key) \
127 * TYPED_HASH_KEYS_ITERATE(key_t, phash, key)
128 * #define foo_hash_keys_iterate_end HASH_KEYS_ITERATE_END
130 * #define foo_hash_iterate(phash, key, data) \
131 * TYPED_HASH_ITERATE(key_t, data_t, phash, key, data)
132 * #define foo_hash_iterate_end HASH_ITERATE_END
134 * Note this is not protected against multiple inclusions; this is so that
135 * you can have multiple different speclists. For each speclist, this file
136 * should be included _once_, inside a .h file which _is_ itself protected
137 * against multiple inclusions. */
139 #ifdef __cplusplus
140 extern "C" {
141 #endif /* __cplusplus */
143 /* utility */
144 #include "genhash.h"
145 #include "iterator.h"
146 #include "support.h"
148 /* Pre-defined cases for convenience. */
149 #ifdef SPECHASH_INT_KEY_TYPE
150 #undef SPECHASH_INT_KEY_TYPE
151 #define SPECHASH_UKEY_TYPE int
152 #define SPECHASH_IKEY_TYPE void *
153 #define SPECHASH_IKEY_TO_UKEY FC_PTR_TO_INT
154 #define SPECHASH_UKEY_TO_IKEY FC_INT_TO_PTR
155 #define SPECHASH_IKEY_VAL NULL
156 #define SPECHASH_IKEY_COMP NULL
157 #define SPECHASH_IKEY_COPY NULL
158 #define SPECHASH_IKEY_FREE NULL
159 #endif/* SPECHASH_INT_KEY_TYPE */
160 #ifdef SPECHASH_INT_DATA_TYPE
161 #undef SPECHASH_INT_DATA_TYPE
162 #define SPECHASH_UDATA_TYPE int
163 #define SPECHASH_IDATA_TYPE void *
164 #define SPECHASH_IDATA_TO_UDATA FC_PTR_TO_INT
165 #define SPECHASH_UDATA_TO_IDATA FC_INT_TO_PTR
166 #define SPECHASH_IDATA_COMP NULL
167 #define SPECHASH_IDATA_COPY NULL
168 #define SPECHASH_IDATA_FREE NULL
169 #endif/* SPECHASH_INT_DATA_TYPE */
170 #ifdef SPECHASH_ENUM_KEY_TYPE
171 #define SPECHASH_UKEY_TYPE enum SPECHASH_ENUM_KEY_TYPE
172 #define SPECHASH_IKEY_TYPE void *
173 #define SPECHASH_IKEY_TO_UKEY FC_PTR_TO_INT
174 #define SPECHASH_UKEY_TO_IKEY FC_INT_TO_PTR
175 #define SPECHASH_IKEY_VAL NULL
176 #define SPECHASH_IKEY_COMP NULL
177 #define SPECHASH_IKEY_COPY NULL
178 #define SPECHASH_IKEY_FREE NULL
179 #endif/* SPECHASH_ENUM_KEY_TYPE */
180 #ifdef SPECHASH_ENUM_DATA_TYPE
181 #define SPECHASH_UDATA_TYPE enum SPECHASH_ENUM_DATA_TYPE
182 #define SPECHASH_IDATA_TYPE void *
183 #define SPECHASH_IDATA_TO_UDATA FC_PTR_TO_INT
184 #define SPECHASH_UDATA_TO_IDATA FC_INT_TO_PTR
185 #define SPECHASH_IDATA_COMP NULL
186 #define SPECHASH_IDATA_COPY NULL
187 #define SPECHASH_IDATA_FREE NULL
188 #endif/* SPECHASH_ENUM_DATA_TYPE */
189 #ifdef SPECHASH_ASTR_KEY_TYPE
190 #undef SPECHASH_ASTR_KEY_TYPE
191 #define SPECHASH_IKEY_TYPE char *
192 #define SPECHASH_IKEY_VAL genhash_str_val_func
193 #define SPECHASH_IKEY_COMP genhash_str_comp_func
194 #define SPECHASH_IKEY_COPY genhash_str_copy_func
195 #define SPECHASH_IKEY_FREE genhash_str_free_func
196 #endif /* SPECHASH_ASTR_KEY_TYPE */
197 #ifdef SPECHASH_ASTR_DATA_TYPE
198 #undef SPECHASH_ASTR_DATA_TYPE
199 #define SPECHASH_IDATA_TYPE char *
200 #define SPECHASH_IDATA_COMP genhash_str_comp_func
201 #define SPECHASH_IDATA_COPY genhash_str_copy_func
202 #define SPECHASH_IDATA_FREE genhash_str_free_func
203 #endif /* SPECHASH_ASTR_DATA_TYPE */
204 #ifdef SPECHASH_CSTR_KEY_TYPE
205 #undef SPECHASH_CSTR_KEY_TYPE
206 #define SPECHASH_IKEY_TYPE char *
207 #define SPECHASH_IKEY_VAL genhash_str_val_func
208 #define SPECHASH_IKEY_COMP genhash_str_comp_func
209 #define SPECHASH_IKEY_COPY NULL
210 #define SPECHASH_IKEY_FREE NULL
211 #endif /* SPECHASH_CSTR_KEY_TYPE */
212 #ifdef SPECHASH_CSTR_DATA_TYPE
213 #undef SPECHASH_CSTR_DATA_TYPE
214 #define SPECHASH_IDATA_TYPE char *
215 #define SPECHASH_IDATA_COMP genhash_str_comp_func
216 #define SPECHASH_IDATA_COPY NULL
217 #define SPECHASH_IDATA_FREE NULL
218 #endif /* SPECHASH_CSTR_DATA_TYPE */
220 #ifndef SPECHASH_TAG
221 #error Must define a SPECHASH_TAG to use this header
222 #endif
223 #ifndef SPECHASH_IKEY_TYPE
224 #error Must define a SPECHASH_IKEY_TYPE to use this header
225 #endif
226 #ifndef SPECHASH_UKEY_TYPE
227 #define SPECHASH_UKEY_TYPE SPECHASH_IKEY_TYPE
228 #endif
229 #ifndef SPECHASH_IDATA_TYPE
230 #error Must define a SPECHASH_IDATA_TYPE to use this header
231 #endif
232 #ifndef SPECHASH_UDATA_TYPE
233 #define SPECHASH_UDATA_TYPE SPECHASH_IDATA_TYPE
234 #endif
236 /* Default functions. */
237 #ifndef SPECHASH_IKEY_VAL
238 #define SPECHASH_IKEY_VAL NULL
239 #endif
240 #ifndef SPECHASH_IKEY_COMP
241 #define SPECHASH_IKEY_COMP NULL
242 #endif
243 #ifndef SPECHASH_IKEY_COPY
244 #define SPECHASH_IKEY_COPY NULL
245 #endif
246 #ifndef SPECHASH_IKEY_FREE
247 #define SPECHASH_IKEY_FREE NULL
248 #endif
249 #ifndef SPECHASH_IDATA_COMP
250 #define SPECHASH_IDATA_COMP NULL
251 #endif
252 #ifndef SPECHASH_IDATA_COPY
253 #define SPECHASH_IDATA_COPY NULL
254 #endif
255 #ifndef SPECHASH_IDATA_FREE
256 #define SPECHASH_IDATA_FREE NULL
257 #endif
259 /* Other functions or macros. */
260 #ifndef SPECHASH_UKEY_TO_IKEY
261 #define SPECHASH_UKEY_TO_IKEY(ukey) ((SPECHASH_IKEY_TYPE) (ukey))
262 #endif
263 #ifndef SPECHASH_IKEY_TO_UKEY
264 #define SPECHASH_IKEY_TO_UKEY(ikey) ((SPECHASH_UKEY_TYPE) (ikey))
265 #endif
266 #ifndef SPECHASH_UDATA_TO_IDATA
267 #define SPECHASH_UDATA_TO_IDATA(udata) ((SPECHASH_IDATA_TYPE) (udata))
268 #endif
269 #ifndef SPECHASH_IDATA_TO_UDATA
270 #define SPECHASH_IDATA_TO_UDATA(idata) ((SPECHASH_UDATA_TYPE) (idata))
271 #endif
273 #define SPECHASH_PASTE_(x, y) x ## y
274 #define SPECHASH_PASTE(x, y) SPECHASH_PASTE_(x, y)
276 #define SPECHASH_HASH struct SPECHASH_PASTE(SPECHASH_TAG, _hash)
277 #define SPECHASH_ITER struct SPECHASH_PASTE(SPECHASH_TAG, _hash_iter)
278 #define SPECHASH_FOO(suffix) SPECHASH_PASTE(SPECHASH_TAG, suffix)
280 /* Dummy type. Actually a genhash, and not defined anywhere. */
281 SPECHASH_HASH;
283 /* Dummy type. Actually a genhash_iter, and not defined anywhere. */
284 SPECHASH_ITER;
286 /* Function related typedefs. */
287 typedef genhash_val_t
288 (*SPECHASH_FOO(_hash_key_val_fn_t)) (const SPECHASH_IKEY_TYPE);
289 typedef bool (*SPECHASH_FOO(_hash_key_comp_fn_t)) (const SPECHASH_IKEY_TYPE,
290 const SPECHASH_IKEY_TYPE);
291 typedef SPECHASH_IKEY_TYPE
292 (*SPECHASH_FOO(_hash_key_copy_fn_t)) (const SPECHASH_IKEY_TYPE);
293 typedef void (*SPECHASH_FOO(_hash_key_free_fn_t)) (SPECHASH_IKEY_TYPE);
294 typedef bool
295 (*SPECHASH_FOO(_hash_data_comp_fn_t)) (const SPECHASH_IDATA_TYPE,
296 const SPECHASH_IDATA_TYPE);
297 typedef SPECHASH_IDATA_TYPE
298 (*SPECHASH_FOO(_hash_data_copy_fn_t)) (const SPECHASH_IDATA_TYPE);
299 typedef void (*SPECHASH_FOO(_hash_data_free_fn_t)) (SPECHASH_IDATA_TYPE);
301 static inline SPECHASH_HASH *SPECHASH_FOO(_hash_new) (void)
302 fc__warn_unused_result;
303 static inline SPECHASH_HASH *
304 SPECHASH_FOO(_hash_new_full) (SPECHASH_FOO(_hash_key_val_fn_t) key_val_func,
305 SPECHASH_FOO(_hash_key_comp_fn_t)
306 key_comp_func,
307 SPECHASH_FOO(_hash_key_copy_fn_t)
308 key_copy_func,
309 SPECHASH_FOO(_hash_key_free_fn_t)
310 key_free_func,
311 SPECHASH_FOO(_hash_data_copy_fn_t)
312 data_copy_func,
313 SPECHASH_FOO(_hash_data_free_fn_t)
314 data_free_func)
315 fc__warn_unused_result;
316 static inline SPECHASH_HASH *
317 SPECHASH_FOO(_hash_new_nentries) (size_t nentries)
318 fc__warn_unused_result;
319 static inline SPECHASH_HASH *
320 SPECHASH_FOO(_hash_new_nentries_full) (SPECHASH_FOO(_hash_key_val_fn_t)
321 key_val_func,
322 SPECHASH_FOO(_hash_key_comp_fn_t)
323 key_comp_func,
324 SPECHASH_FOO(_hash_key_copy_fn_t)
325 key_copy_func,
326 SPECHASH_FOO(_hash_key_free_fn_t)
327 key_free_func,
328 SPECHASH_FOO(_hash_data_copy_fn_t)
329 data_copy_func,
330 SPECHASH_FOO(_hash_data_free_fn_t)
331 data_free_func, size_t nentries)
332 fc__warn_unused_result;
334 /****************************************************************************
335 Create a new spechash.
336 ****************************************************************************/
337 static inline SPECHASH_HASH *SPECHASH_FOO(_hash_new) (void)
339 return SPECHASH_FOO(_hash_new_full) (SPECHASH_IKEY_VAL,
340 SPECHASH_IKEY_COMP,
341 SPECHASH_IKEY_COPY,
342 SPECHASH_IKEY_FREE,
343 SPECHASH_IDATA_COPY,
344 SPECHASH_IDATA_FREE);
347 /****************************************************************************
348 Create a new spechash with a set of control functions.
349 ****************************************************************************/
350 static inline SPECHASH_HASH *
351 SPECHASH_FOO(_hash_new_full) (SPECHASH_FOO(_hash_key_val_fn_t) key_val_func,
352 SPECHASH_FOO(_hash_key_comp_fn_t)
353 key_comp_func,
354 SPECHASH_FOO(_hash_key_copy_fn_t)
355 key_copy_func,
356 SPECHASH_FOO(_hash_key_free_fn_t)
357 key_free_func,
358 SPECHASH_FOO(_hash_data_copy_fn_t)
359 data_copy_func,
360 SPECHASH_FOO(_hash_data_free_fn_t)
361 data_free_func)
363 return ((SPECHASH_HASH *)
364 genhash_new_full((genhash_val_fn_t) key_val_func,
365 (genhash_comp_fn_t) key_comp_func,
366 (genhash_copy_fn_t) key_copy_func,
367 (genhash_free_fn_t) key_free_func,
368 (genhash_copy_fn_t) data_copy_func,
369 (genhash_free_fn_t) data_free_func));
372 /****************************************************************************
373 Create a new spechash with n entries.
374 ****************************************************************************/
375 static inline SPECHASH_HASH *
376 SPECHASH_FOO(_hash_new_nentries) (size_t nentries)
378 return SPECHASH_FOO(_hash_new_nentries_full) (SPECHASH_IKEY_VAL,
379 SPECHASH_IKEY_COMP,
380 SPECHASH_IKEY_COPY,
381 SPECHASH_IKEY_FREE,
382 SPECHASH_IDATA_COPY,
383 SPECHASH_IDATA_FREE,
384 nentries);
387 /****************************************************************************
388 Create a new spechash with n entries and a set of control functions.
389 ****************************************************************************/
390 static inline SPECHASH_HASH *
391 SPECHASH_FOO(_hash_new_nentries_full) (SPECHASH_FOO(_hash_key_val_fn_t)
392 key_val_func,
393 SPECHASH_FOO(_hash_key_comp_fn_t)
394 key_comp_func,
395 SPECHASH_FOO(_hash_key_copy_fn_t)
396 key_copy_func,
397 SPECHASH_FOO(_hash_key_free_fn_t)
398 key_free_func,
399 SPECHASH_FOO(_hash_data_copy_fn_t)
400 data_copy_func,
401 SPECHASH_FOO(_hash_data_free_fn_t)
402 data_free_func, size_t nentries)
404 return ((SPECHASH_HASH *)
405 genhash_new_nentries_full((genhash_val_fn_t) key_val_func,
406 (genhash_comp_fn_t) key_comp_func,
407 (genhash_copy_fn_t) key_copy_func,
408 (genhash_free_fn_t) key_free_func,
409 (genhash_copy_fn_t) data_copy_func,
410 (genhash_free_fn_t) data_free_func,
411 nentries));
414 /****************************************************************************
415 Free a spechash.
416 ****************************************************************************/
417 static inline void SPECHASH_FOO(_hash_destroy) (SPECHASH_HASH *tthis)
419 genhash_destroy((struct genhash *) tthis);
422 /****************************************************************************
423 Enable/Disable shrinking.
424 ****************************************************************************/
425 static inline bool SPECHASH_FOO(_hash_set_no_shrink) (SPECHASH_HASH *tthis,
426 bool no_shrink)
428 return genhash_set_no_shrink((struct genhash *) tthis, no_shrink);
431 /****************************************************************************
432 Return the number of elements.
433 ****************************************************************************/
434 static inline size_t SPECHASH_FOO(_hash_size) (const SPECHASH_HASH *tthis)
436 return genhash_size((const struct genhash *) tthis);
439 /****************************************************************************
440 Return the real number of buckets.
441 ****************************************************************************/
442 static inline size_t
443 SPECHASH_FOO(_hash_capacity) (const SPECHASH_HASH *tthis)
445 return genhash_capacity((const struct genhash *) tthis);
448 /****************************************************************************
449 Duplicate the spechash.
450 ****************************************************************************/
451 static inline SPECHASH_HASH *
452 SPECHASH_FOO(_hash_copy) (const SPECHASH_HASH *tthis)
453 fc__warn_unused_result;
455 static inline SPECHASH_HASH *
456 SPECHASH_FOO(_hash_copy) (const SPECHASH_HASH *tthis)
458 return (SPECHASH_HASH *) genhash_copy((const struct genhash *) tthis);
461 /****************************************************************************
462 Remove all elements of the spechash.
463 ****************************************************************************/
464 static inline void SPECHASH_FOO(_hash_clear) (SPECHASH_HASH *tthis)
466 genhash_clear((struct genhash *) tthis);
469 /****************************************************************************
470 Insert an element into the spechash. Returns TRUE on success (if no
471 collision).
472 ****************************************************************************/
473 static inline bool
474 SPECHASH_FOO(_hash_insert) (SPECHASH_HASH *tthis,
475 const SPECHASH_UKEY_TYPE ukey,
476 const SPECHASH_UDATA_TYPE udata)
478 return genhash_insert((struct genhash *) tthis,
479 SPECHASH_UKEY_TO_IKEY(ukey),
480 SPECHASH_UDATA_TO_IDATA(udata));
483 /****************************************************************************
484 Replace an element into the spechash. Returns TRUE if it replaced an old
485 element.
486 ****************************************************************************/
487 static inline bool
488 SPECHASH_FOO(_hash_replace) (SPECHASH_HASH *tthis,
489 const SPECHASH_UKEY_TYPE ukey,
490 const SPECHASH_UDATA_TYPE udata)
492 return genhash_replace((struct genhash *) tthis,
493 SPECHASH_UKEY_TO_IKEY(ukey),
494 SPECHASH_UDATA_TO_IDATA(udata));
497 /****************************************************************************
498 Replace an element into the spechash. Returns TRUE if it replaced an old
499 element.
500 ****************************************************************************/
501 static inline bool
502 SPECHASH_FOO(_hash_replace_full) (SPECHASH_HASH *tthis,
503 const SPECHASH_UKEY_TYPE ukey,
504 const SPECHASH_UDATA_TYPE udata,
505 SPECHASH_UKEY_TYPE *old_pukey,
506 SPECHASH_UDATA_TYPE *old_pudata)
508 void *key_ptr, *data_ptr;
509 bool ret = genhash_replace_full((struct genhash *) tthis,
510 SPECHASH_UKEY_TO_IKEY(ukey),
511 SPECHASH_UDATA_TO_IDATA(udata),
512 &key_ptr, &data_ptr);
514 if (NULL != old_pukey) {
515 *old_pukey = SPECHASH_IKEY_TO_UKEY((SPECHASH_IKEY_TYPE) key_ptr);
517 if (NULL != old_pudata) {
518 *old_pudata = SPECHASH_IDATA_TO_UDATA((SPECHASH_IDATA_TYPE) data_ptr);
520 return ret;
523 /****************************************************************************
524 Lookup an element. Returns TRUE if found.
525 ****************************************************************************/
526 static inline bool
527 SPECHASH_FOO(_hash_lookup) (const SPECHASH_HASH *tthis,
528 const SPECHASH_UKEY_TYPE ukey,
529 SPECHASH_UDATA_TYPE *pudata)
531 void *data_ptr;
532 bool ret = genhash_lookup((const struct genhash *) tthis,
533 SPECHASH_UKEY_TO_IKEY(ukey), &data_ptr);
535 if (NULL != pudata) {
536 *pudata = SPECHASH_IDATA_TO_UDATA((SPECHASH_IDATA_TYPE) data_ptr);
538 return ret;
541 /****************************************************************************
542 Remove an element. Returns TRUE on success.
543 ****************************************************************************/
544 static inline bool
545 SPECHASH_FOO(_hash_remove) (SPECHASH_HASH *tthis,
546 const SPECHASH_UKEY_TYPE ukey)
548 return genhash_remove((struct genhash *) tthis,
549 SPECHASH_UKEY_TO_IKEY(ukey));
552 /****************************************************************************
553 Remove an element. Returns TRUE on success.
554 ****************************************************************************/
555 static inline bool
556 SPECHASH_FOO(_hash_remove_full) (SPECHASH_HASH *tthis,
557 const SPECHASH_UKEY_TYPE ukey,
558 SPECHASH_UKEY_TYPE *deleted_pukey,
559 SPECHASH_UDATA_TYPE *deleted_pudata)
561 void *key_ptr, *data_ptr;
562 bool ret = genhash_remove_full((struct genhash *) tthis,
563 SPECHASH_UKEY_TO_IKEY(ukey),
564 &key_ptr, &data_ptr);
566 if (NULL != deleted_pukey) {
567 *deleted_pukey = SPECHASH_IKEY_TO_UKEY((SPECHASH_IKEY_TYPE) key_ptr);
569 if (NULL != deleted_pudata) {
570 *deleted_pudata = SPECHASH_IDATA_TO_UDATA((SPECHASH_IDATA_TYPE)
571 data_ptr);
573 return ret;
577 /****************************************************************************
578 Compare the specific hash tables.
579 ****************************************************************************/
580 static inline bool
581 SPECHASH_FOO(_hashs_are_equal_full) (const SPECHASH_HASH *phash1,
582 const SPECHASH_HASH *phash2,
583 SPECHASH_FOO(_hash_data_comp_fn_t)
584 data_comp_func)
586 return genhashs_are_equal_full((const struct genhash *) phash1,
587 (const struct genhash *) phash2,
588 (genhash_comp_fn_t) data_comp_func);
591 /****************************************************************************
592 Compare the specific hash tables.
593 ****************************************************************************/
594 static inline bool
595 SPECHASH_FOO(_hashs_are_equal) (const SPECHASH_HASH *phash1,
596 const SPECHASH_HASH *phash2)
598 return SPECHASH_FOO(_hashs_are_equal_full) (phash1, phash2,
599 SPECHASH_IDATA_COMP);
603 /****************************************************************************
604 Remove the size of the iterator type.
605 ****************************************************************************/
606 static inline size_t SPECHASH_FOO(_hash_iter_sizeof) (void)
608 return genhash_iter_sizeof();
611 /****************************************************************************
612 Initialize an iterator.
613 ****************************************************************************/
614 static inline struct iterator *
615 SPECHASH_FOO(_hash_iter_init) (SPECHASH_ITER *iter,
616 const SPECHASH_HASH *tthis)
618 return genhash_iter_init((struct genhash_iter *) iter,
619 (const struct genhash *) tthis);
622 /****************************************************************************
623 Initialize a key iterator.
624 ****************************************************************************/
625 static inline struct iterator *
626 SPECHASH_FOO(_hash_key_iter_init) (SPECHASH_ITER *iter,
627 const SPECHASH_HASH *tthis)
629 return genhash_key_iter_init((struct genhash_iter *) iter,
630 (const struct genhash *) tthis);
633 /****************************************************************************
634 Initialize a value iterator.
635 ****************************************************************************/
636 static inline struct iterator *
637 SPECHASH_FOO(_hash_value_iter_init) (SPECHASH_ITER *iter,
638 const SPECHASH_HASH *tthis)
640 return genhash_value_iter_init((struct genhash_iter *) iter,
641 (const struct genhash *) tthis);
644 #undef SPECHASH_TAG
645 #undef SPECHASH_IKEY_TYPE
646 #undef SPECHASH_UKEY_TYPE
647 #undef SPECHASH_IDATA_TYPE
648 #undef SPECHASH_UDATA_TYPE
649 #undef SPECHASH_IKEY_VAL
650 #undef SPECHASH_IKEY_COMP
651 #undef SPECHASH_IKEY_COPY
652 #undef SPECHASH_IKEY_FREE
653 #undef SPECHASH_IDATA_COMP
654 #undef SPECHASH_IDATA_COPY
655 #undef SPECHASH_IDATA_FREE
656 #undef SPECHASH_UKEY_TO_IKEY
657 #undef SPECHASH_IKEY_TO_UKEY
658 #undef SPECHASH_UDATA_TO_IDATA
659 #undef SPECHASH_IDATA_TO_UDATA
660 #undef SPECHASH_PASTE_
661 #undef SPECHASH_PASTE
662 #undef SPECHASH_HASH
663 #undef SPECHASH_ITER
664 #undef SPECHASH_FOO
665 #ifdef SPECHASH_ENUM_KEY_TYPE
666 #undef SPECHASH_ENUM_KEY_TYPE
667 #endif
668 #ifdef SPECHASH_ENUM_DATA_TYPE
669 #undef SPECHASH_ENUM_DATA_TYPE
670 #endif
673 /* Base macros that the users can specialize. */
674 #ifndef FC__SPECHASH_H /* Defines this only once, no multiple inclusions. */
675 #define FC__SPECHASH_H
677 /* Spechash value iterator.
679 * TYPE_data - The real type of the data in the genhash.
680 * ARG_ht - The genhash to iterate.
681 * NAME_data - The name of the data iterator (defined inside the macro). */
682 #define TYPED_HASH_DATA_ITERATE(TYPE_data, ARG_ht, NAME_data) \
683 generic_iterate(struct genhash_iter, TYPE_data, NAME_data, \
684 genhash_iter_sizeof, genhash_value_iter_init, \
685 (const struct genhash *) (ARG_ht))
687 /* Balance for above: */
688 #define HASH_DATA_ITERATE_END generic_iterate_end
690 /* Spechash key iterator.
692 * TYPE_key - The real type of the key in the genhash.
693 * ARG_ht - The genhash to iterate.
694 * NAME_key - The name of the key iterator (defined inside the macro). */
695 #define TYPED_HASH_KEYS_ITERATE(TYPE_key, ARG_ht, NAME_key) \
696 generic_iterate(struct genhash_iter, TYPE_key, NAME_key, \
697 genhash_iter_sizeof, genhash_key_iter_init, \
698 (const struct genhash *) (ARG_ht))
700 /* Balance for above: */
701 #define HASH_KEYS_ITERATE_END \
703 } while (FALSE);
705 /* Spechash key and values iterator.
707 * TYPE_key - The real type of the key in the genhash.
708 * TYPE_data - The real type of the key in the genhash.
709 * ARG_ht - The genhash to iterate.
710 * NAME_key - The name of the key iterator (defined inside the macro).
711 * NAME_data - The name of the data iterator (defined inside the macro). */
712 #define TYPED_HASH_ITERATE(TYPE_key, TYPE_data, ARG_ht, NAME_key, NAME_data)\
713 genhash_iterate((const struct genhash *) (ARG_ht), MY_iter) { \
714 TYPE_key NAME_key = (TYPE_key) genhash_iter_key(MY_iter); \
715 TYPE_data NAME_data = (TYPE_data) genhash_iter_value(MY_iter);
717 /* Balance for above: */
718 #define HASH_ITERATE_END \
719 } genhash_iterate_end;
721 #endif /* FC__SPECHASH_H */
723 /* This is after #endif FC__SPECHASH_H on purpose.
724 extern "C" portion begins well before latter part of the header
725 is guarded against multiple inclusions. */
726 #ifdef __cplusplus
728 #endif /* __cplusplus */