Support changing players' science box in the editor.
[freeciv.git] / utility / spechash.h
blob5ef09cf47da880956bc071d6f2fba4c5e2dacb7f
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_KEY_TYPE - the typed genhash will use this type as key.
23 * SPECHASH_DATA_TYPE - the typed genhash will use this type as data.
24 * You may also define:
25 * SPECHASH_KEY_VAL - The default hash function.
26 * SPECHASH_KEY_COMP - The default hash key comparator function.
27 * SPECHASH_KEY_COPY - The default key copy function.
28 * SPECHASH_KEY_FREE - The default key free function.
29 * SPECHASH_DATA_COMP - The default data comparator function.
30 * SPECHASH_DATA_COPY - The default data copy function.
31 * SPECHASH_DATA_FREE - The default data free function.
32 * SPECHASH_KEY_TO_PTR - A function or macro to convert a key to pointer.
33 * SPECHASH_PTR_TO_KEY - A function or macro to convert a pointer to key.
34 * SPECHASH_DATA_TO_PTR - A function or macro to convert a data to pointer.
35 * SPECHASH_PTR_TO_DATA - A function or macro to convert a pointer to data.
36 * At the end of this file, these (and other defines) are undef-ed.
38 * Assuming SPECHASH_TAG were 'foo', SPECHASH_KEY_TYPE were 'key_t', and
39 * SPECHASH_DATA_TYPE were 'data_t'.
40 * including this file would provide a struct definition for:
41 * struct foo_hash;
42 * struct foo_hash_iter;
44 * function typedefs:
45 * typedef genhash_val_t (*foo_hash_key_val_fn_t) (const key_t, size_t);
46 * typedef bool (*foo_hash_key_comp_fn_t) (const key_t, const key_t);
47 * typedef key_t (*foo_hash_key_copy_fn_t) (const key_t);
48 * typedef void (*foo_hash_key_free_fn_t) (key_t);
49 * typedef bool (*foo_hash_data_comp_fn_t) (const data_t, const data_t);
50 * typedef data_t (*foo_hash_data_copy_fn_t) (const data_t);
51 * typedef void (*foo_hash_data_free_fn_t) (data_t);
53 * and prototypes for the following functions:
54 * struct foo_hash *foo_hash_new(void);
55 * struct foo_hash *foo_hash_new_full(foo_hash_key_val_fn_t key_val,
56 * foo_hash_key_comp_fn_t key_comp,
57 * foo_hash_key_copy_fn_t key_copy,
58 * foo_hash_key_free_fn_t key_free,
59 * foo_hash_data_copy_fn_t data_val,
60 * foo_hash_data_free_fn_t data_free);
61 * struct foo_hash *foo_hash_new_nentries(size_t nentries);
62 * struct foo_hash *
63 * foo_hash_new_nentries_full(foo_hash_key_val_fn_t key_val,
64 * foo_hash_key_comp_fn_t key_comp,
65 * foo_hash_key_copy_fn_t key_copy,
66 * foo_hash_key_free_fn_t key_free,
67 * foo_hash_data_copy_fn_t data_val,
68 * foo_hash_data_free_fn_t data_free,
69 * size_t nentries);
70 * void foo_hash_destroy(struct foo_hash *phash);
71 * bool foo_hash_set_no_shrink(struct foo_hash *phash, bool no_shrink);
72 * size_t foo_hash_size(const struct foo_hash *phash);
73 * size_t foo_hash_capacity(const struct foo_hash *phash);
74 * struct foo_hash *foo_hash_copy(const struct foo_hash *phash);
75 * void foo_hash_clear(struct foo_hash *phash);
76 * bool foo_hash_insert(struct foo_hash *phash, const key_t key,
77 * const data_t data);
78 * bool foo_hash_replace(struct foo_hash *phash, const key_t key,
79 * const data_t data);
80 * bool foo_hash_replace_full(struct foo_hash *phash, const key_t key,
81 * const data_t data, key_t *old_pkey,
82 * data_t *old_pdata);
83 * bool foo_hash_lookup(const struct foo_hash *phash, const key_t key,
84 * data_t *pdata);
85 * bool foo_hash_remove(struct foo_hash *phash, const key_t key);
86 * bool foo_hash_remove_full(struct foo_hash *phash, const key_t key,
87 * key_t *deleted_pkey, data_t *deleted_pdata);
89 * bool foo_hashs_are_equal(const struct foo_hash *phash1,
90 * const struct foo_hash *phash2);
91 * bool foo_hashs_are_equal_full(const struct foo_hash *phash1,
92 * const struct foo_hash *phash2,
93 * foo_hash_data_comp_fn_t data_comp_func);
95 * size_t foo_hash_iter_sizeof(void);
96 * struct iterator *foo_hash_iter_init(struct foo_hash_iter *iter,
97 * const struct foo_hash *phash);
98 * struct iterator *foo_hash_key_iter_init(struct foo_hash_iter *iter,
99 * const struct foo_hash *phash);
100 * struct iterator *foo_hash_value_init(struct foo_hash_iter *iter,
101 * const struct foo_hash *phash);
103 * You should also define yourself (this file cannot do this for you):
104 * #define foo_hash_data_iterate(phash, data) \
105 * TYPED_HASH_DATA_ITERATE(data_t, phash, data)
106 * #define foo_hash_data_iterate_end HASH_DATA_ITERATE_END
108 * #define foo_hash_keys_iterate(phash, key) \
109 * TYPED_HASH_KEYS_ITERATE(key_t, phash, key)
110 * #define foo_hash_keys_iterate_end HASH_KEYS_ITERATE_END
112 * #define foo_hash_iterate(phash, key, data) \
113 * TYPED_HASH_ITERATE(key_t, data_t, phash, key, data)
114 * #define foo_hash_iterate_end HASH_ITERATE_END
116 * Note this is not protected against multiple inclusions; this is so that
117 * you can have multiple different speclists. For each speclist, this file
118 * should be included _once_, inside a .h file which _is_ itself protected
119 * against multiple inclusions. */
121 #ifdef __cplusplus
122 extern "C" {
123 #endif /* __cplusplus */
125 /* utility */
126 #include "genhash.h"
127 #include "iterator.h"
128 #include "support.h"
130 #ifndef SPECHASH_TAG
131 #error Must define a SPECHASH_TAG to use this header
132 #endif
133 #ifndef SPECHASH_KEY_TYPE
134 #error Must define a SPECHASH_KEY_TYPE to use this header
135 #endif
136 #ifndef SPECHASH_DATA_TYPE
137 #error Must define a SPECHASH_DATA_TYPE to use this header
138 #endif
140 /* Default functions. */
141 #ifndef SPECHASH_KEY_VAL
142 #define SPECHASH_KEY_VAL genhash_ptr_val_func
143 #endif
144 #ifndef SPECHASH_KEY_COMP
145 #define SPECHASH_KEY_COMP genhash_ptr_comp_func
146 #endif
147 #ifndef SPECHASH_KEY_COPY
148 #define SPECHASH_KEY_COPY NULL
149 #endif
150 #ifndef SPECHASH_KEY_FREE
151 #define SPECHASH_KEY_FREE NULL
152 #endif
153 #ifndef SPECHASH_DATA_COMP
154 #define SPECHASH_DATA_COMP NULL
155 #endif
156 #ifndef SPECHASH_DATA_COPY
157 #define SPECHASH_DATA_COPY NULL
158 #endif
159 #ifndef SPECHASH_DATA_FREE
160 #define SPECHASH_DATA_FREE NULL
161 #endif
163 /* Other functions or macros. */
164 #ifndef SPECHASH_KEY_TO_PTR
165 #define SPECHASH_KEY_TO_PTR(key) (key)
166 #endif
167 #ifndef SPECHASH_PTR_TO_KEY
168 #define SPECHASH_PTR_TO_KEY(ptr) (ptr)
169 #endif
170 #ifndef SPECHASH_DATA_TO_PTR
171 #define SPECHASH_DATA_TO_PTR(data) (data)
172 #endif
173 #ifndef SPECHASH_PTR_TO_DATA
174 #define SPECHASH_PTR_TO_DATA(ptr) (ptr)
175 #endif
177 #define SPECHASH_PASTE_(x, y) x ## y
178 #define SPECHASH_PASTE(x, y) SPECHASH_PASTE_(x, y)
180 #define SPECHASH_HASH struct SPECHASH_PASTE(SPECHASH_TAG, _hash)
181 #define SPECHASH_ITER struct SPECHASH_PASTE(SPECHASH_TAG, _hash_iter)
182 #define SPECHASH_FOO(suffix) SPECHASH_PASTE(SPECHASH_TAG, suffix)
184 /* Dummy type. Actually a genhash, and not defined anywhere. */
185 SPECHASH_HASH;
187 /* Dummy type. Actually a genhash_iter, and not defined anywhere. */
188 SPECHASH_ITER;
190 /* Function related typedefs. */
191 typedef genhash_val_t
192 (*SPECHASH_FOO(_hash_key_val_fn_t)) (const SPECHASH_KEY_TYPE, size_t);
193 typedef bool (*SPECHASH_FOO(_hash_key_comp_fn_t)) (const SPECHASH_KEY_TYPE,
194 const SPECHASH_KEY_TYPE);
195 typedef SPECHASH_KEY_TYPE
196 (*SPECHASH_FOO(_hash_key_copy_fn_t)) (const SPECHASH_KEY_TYPE);
197 typedef void (*SPECHASH_FOO(_hash_key_free_fn_t)) (SPECHASH_KEY_TYPE);
198 typedef bool
199 (*SPECHASH_FOO(_hash_data_comp_fn_t)) (const SPECHASH_DATA_TYPE,
200 const SPECHASH_DATA_TYPE);
201 typedef SPECHASH_DATA_TYPE
202 (*SPECHASH_FOO(_hash_data_copy_fn_t)) (const SPECHASH_DATA_TYPE);
203 typedef void (*SPECHASH_FOO(_hash_data_free_fn_t)) (SPECHASH_DATA_TYPE);
205 /****************************************************************************
206 Create a new spechash.
207 ****************************************************************************/
208 static inline SPECHASH_HASH *SPECHASH_FOO(_hash_new) (void)
209 fc__warn_unused_result;
211 static inline SPECHASH_HASH *SPECHASH_FOO(_hash_new) (void)
213 return ((SPECHASH_HASH *)
214 genhash_new_full((genhash_val_fn_t) SPECHASH_KEY_VAL,
215 (genhash_comp_fn_t) SPECHASH_KEY_COMP,
216 (genhash_copy_fn_t) SPECHASH_KEY_COPY,
217 (genhash_free_fn_t) SPECHASH_KEY_FREE,
218 (genhash_copy_fn_t) SPECHASH_DATA_COPY,
219 (genhash_free_fn_t) SPECHASH_DATA_FREE));
222 /****************************************************************************
223 Create a new spechash with a set of control functions.
224 ****************************************************************************/
225 static inline SPECHASH_HASH *
226 SPECHASH_FOO(_hash_new_full) (SPECHASH_FOO(_hash_key_val_fn_t) key_val_func,
227 SPECHASH_FOO(_hash_key_comp_fn_t)
228 key_comp_func,
229 SPECHASH_FOO(_hash_key_copy_fn_t)
230 key_copy_func,
231 SPECHASH_FOO(_hash_key_free_fn_t)
232 key_free_func,
233 SPECHASH_FOO(_hash_data_copy_fn_t)
234 data_copy_func,
235 SPECHASH_FOO(_hash_data_free_fn_t)
236 data_free_func)
237 fc__warn_unused_result;
239 static inline SPECHASH_HASH *
240 SPECHASH_FOO(_hash_new_full) (SPECHASH_FOO(_hash_key_val_fn_t) key_val_func,
241 SPECHASH_FOO(_hash_key_comp_fn_t)
242 key_comp_func,
243 SPECHASH_FOO(_hash_key_copy_fn_t)
244 key_copy_func,
245 SPECHASH_FOO(_hash_key_free_fn_t)
246 key_free_func,
247 SPECHASH_FOO(_hash_data_copy_fn_t)
248 data_copy_func,
249 SPECHASH_FOO(_hash_data_free_fn_t)
250 data_free_func)
252 return ((SPECHASH_HASH *)
253 genhash_new_full((genhash_val_fn_t) key_val_func,
254 (genhash_comp_fn_t) key_comp_func,
255 (genhash_copy_fn_t) key_copy_func,
256 (genhash_free_fn_t) key_free_func,
257 (genhash_copy_fn_t) data_copy_func,
258 (genhash_free_fn_t) data_free_func));
261 /****************************************************************************
262 Create a new spechash with n entries.
263 ****************************************************************************/
264 static inline SPECHASH_HASH *
265 SPECHASH_FOO(_hash_new_nentries) (size_t nentries)
266 fc__warn_unused_result;
268 static inline SPECHASH_HASH *
269 SPECHASH_FOO(_hash_new_nentries) (size_t nentries)
271 return ((SPECHASH_HASH *)
272 genhash_new_nentries_full((genhash_val_fn_t) SPECHASH_KEY_VAL,
273 (genhash_comp_fn_t) SPECHASH_KEY_COMP,
274 (genhash_copy_fn_t) SPECHASH_KEY_COPY,
275 (genhash_free_fn_t) SPECHASH_KEY_FREE,
276 (genhash_copy_fn_t) SPECHASH_DATA_COPY,
277 (genhash_free_fn_t) SPECHASH_DATA_FREE,
278 nentries));
281 /****************************************************************************
282 Create a new spechash with n entries and a set of control functions.
283 ****************************************************************************/
284 static inline SPECHASH_HASH *
285 SPECHASH_FOO(_hash_new_nentries_full) (SPECHASH_FOO(_hash_key_val_fn_t)
286 key_val_func,
287 SPECHASH_FOO(_hash_key_comp_fn_t)
288 key_comp_func,
289 SPECHASH_FOO(_hash_key_copy_fn_t)
290 key_copy_func,
291 SPECHASH_FOO(_hash_key_free_fn_t)
292 key_free_func,
293 SPECHASH_FOO(_hash_data_copy_fn_t)
294 data_copy_func,
295 SPECHASH_FOO(_hash_data_free_fn_t)
296 data_free_func, size_t nentries)
297 fc__warn_unused_result;
299 static inline SPECHASH_HASH *
300 SPECHASH_FOO(_hash_new_nentries_full) (SPECHASH_FOO(_hash_key_val_fn_t)
301 key_val_func,
302 SPECHASH_FOO(_hash_key_comp_fn_t)
303 key_comp_func,
304 SPECHASH_FOO(_hash_key_copy_fn_t)
305 key_copy_func,
306 SPECHASH_FOO(_hash_key_free_fn_t)
307 key_free_func,
308 SPECHASH_FOO(_hash_data_copy_fn_t)
309 data_copy_func,
310 SPECHASH_FOO(_hash_data_free_fn_t)
311 data_free_func, size_t nentries)
313 return ((SPECHASH_HASH *)
314 genhash_new_nentries_full((genhash_val_fn_t) key_val_func,
315 (genhash_comp_fn_t) key_comp_func,
316 (genhash_copy_fn_t) key_copy_func,
317 (genhash_free_fn_t) key_free_func,
318 (genhash_copy_fn_t) data_copy_func,
319 (genhash_free_fn_t) data_free_func,
320 nentries));
323 /****************************************************************************
324 Free a spechash.
325 ****************************************************************************/
326 static inline void SPECHASH_FOO(_hash_destroy) (SPECHASH_HASH *tthis)
328 genhash_destroy((struct genhash *) tthis);
331 /****************************************************************************
332 Enable/Disable shrinking.
333 ****************************************************************************/
334 static inline bool SPECHASH_FOO(_hash_set_no_shrink) (SPECHASH_HASH *tthis,
335 bool no_shrink)
337 return genhash_set_no_shrink((struct genhash *) tthis, no_shrink);
340 /****************************************************************************
341 Return the number of elements.
342 ****************************************************************************/
343 static inline size_t SPECHASH_FOO(_hash_size) (const SPECHASH_HASH *tthis)
345 return genhash_size((const struct genhash *) tthis);
348 /****************************************************************************
349 Return the real number of buckets.
350 ****************************************************************************/
351 static inline size_t
352 SPECHASH_FOO(_hash_capacity) (const SPECHASH_HASH *tthis)
354 return genhash_capacity((const struct genhash *) tthis);
357 /****************************************************************************
358 Duplicate the spechash.
359 ****************************************************************************/
360 static inline SPECHASH_HASH *
361 SPECHASH_FOO(_hash_copy) (const SPECHASH_HASH *tthis)
362 fc__warn_unused_result;
364 static inline SPECHASH_HASH *
365 SPECHASH_FOO(_hash_copy) (const SPECHASH_HASH *tthis)
367 return (SPECHASH_HASH *) genhash_copy((const struct genhash *) tthis);
370 /****************************************************************************
371 Remove all elements of the spechash.
372 ****************************************************************************/
373 static inline void SPECHASH_FOO(_hash_clear) (SPECHASH_HASH *tthis)
375 genhash_clear((struct genhash *) tthis);
378 /****************************************************************************
379 Insert an element into the spechash. Returns TRUE on success (if no
380 collision).
381 ****************************************************************************/
382 static inline bool SPECHASH_FOO(_hash_insert) (SPECHASH_HASH *tthis,
383 const SPECHASH_KEY_TYPE key,
384 const SPECHASH_DATA_TYPE data)
386 return genhash_insert((struct genhash *) tthis, SPECHASH_KEY_TO_PTR(key),
387 SPECHASH_DATA_TO_PTR(data));
390 /****************************************************************************
391 Replace an element into the spechash. Returns TRUE if it replaced an old
392 element.
393 ****************************************************************************/
394 static inline bool
395 SPECHASH_FOO(_hash_replace) (SPECHASH_HASH *tthis,
396 const SPECHASH_KEY_TYPE key,
397 const SPECHASH_DATA_TYPE data)
399 return genhash_replace((struct genhash *) tthis, SPECHASH_KEY_TO_PTR(key),
400 SPECHASH_DATA_TO_PTR(data));
403 /****************************************************************************
404 Replace an element into the spechash. Returns TRUE if it replaced an old
405 element.
406 ****************************************************************************/
407 static inline bool
408 SPECHASH_FOO(_hash_replace_full) (SPECHASH_HASH *tthis,
409 const SPECHASH_KEY_TYPE key,
410 const SPECHASH_DATA_TYPE data,
411 SPECHASH_KEY_TYPE *old_pkey,
412 SPECHASH_DATA_TYPE *old_pdata)
414 void *key_ptr, *data_ptr;
415 bool ret = genhash_replace_full((struct genhash *) tthis,
416 SPECHASH_KEY_TO_PTR(key),
417 SPECHASH_DATA_TO_PTR(data),
418 &key_ptr, &data_ptr);
420 if (NULL != old_pkey) {
421 *old_pkey = (SPECHASH_KEY_TYPE) SPECHASH_PTR_TO_KEY(key_ptr);
423 if (NULL != old_pdata) {
424 *old_pdata = (SPECHASH_DATA_TYPE) SPECHASH_PTR_TO_DATA(data_ptr);
426 return ret;
429 /****************************************************************************
430 Lookup an element. Returns TRUE if found.
431 ****************************************************************************/
432 static inline bool SPECHASH_FOO(_hash_lookup) (const SPECHASH_HASH *tthis,
433 const SPECHASH_KEY_TYPE key,
434 SPECHASH_DATA_TYPE *pdata)
436 void *data_ptr;
437 bool ret = genhash_lookup((const struct genhash *) tthis,
438 SPECHASH_KEY_TO_PTR(key), &data_ptr);
440 if (NULL != pdata) {
441 *pdata = (SPECHASH_DATA_TYPE) SPECHASH_PTR_TO_DATA(data_ptr);
443 return ret;
446 /****************************************************************************
447 Remove an element. Returns TRUE on success.
448 ****************************************************************************/
449 static inline bool SPECHASH_FOO(_hash_remove) (SPECHASH_HASH *tthis,
450 const SPECHASH_KEY_TYPE key)
452 return genhash_remove((struct genhash *) tthis, SPECHASH_KEY_TO_PTR(key));
455 /****************************************************************************
456 Remove an element. Returns TRUE on success.
457 ****************************************************************************/
458 static inline bool
459 SPECHASH_FOO(_hash_remove_full) (SPECHASH_HASH *tthis,
460 const SPECHASH_KEY_TYPE key,
461 SPECHASH_KEY_TYPE *deleted_pkey,
462 SPECHASH_DATA_TYPE *deleted_pdata)
464 void *key_ptr, *data_ptr;
465 bool ret = genhash_remove_full((struct genhash *) tthis,
466 SPECHASH_KEY_TO_PTR(key),
467 &key_ptr, &data_ptr);
469 if (NULL != deleted_pkey) {
470 *deleted_pkey = (SPECHASH_KEY_TYPE) SPECHASH_PTR_TO_KEY(key_ptr);
472 if (NULL != deleted_pdata) {
473 *deleted_pdata = (SPECHASH_DATA_TYPE) SPECHASH_PTR_TO_DATA(data_ptr);
475 return ret;
479 /****************************************************************************
480 Compare the specific hash tables.
481 ****************************************************************************/
482 static inline bool
483 SPECHASH_FOO(_hashs_are_equal) (const SPECHASH_HASH *phash1,
484 const SPECHASH_HASH *phash2)
486 return genhashs_are_equal_full((const struct genhash *) phash1,
487 (const struct genhash *) phash2,
488 (genhash_comp_fn_t) SPECHASH_DATA_COMP);
491 /****************************************************************************
492 Compare the specific hash tables.
493 ****************************************************************************/
494 static inline bool
495 SPECHASH_FOO(_hashs_are_equal_full) (const SPECHASH_HASH *phash1,
496 const SPECHASH_HASH *phash2,
497 SPECHASH_FOO(_hash_data_comp_fn_t)
498 data_comp_func)
500 return genhashs_are_equal_full((const struct genhash *) phash1,
501 (const struct genhash *) phash2,
502 (genhash_comp_fn_t) data_comp_func);
506 /****************************************************************************
507 Remove the size of the iterator type.
508 ****************************************************************************/
509 static inline size_t SPECHASH_FOO(_hash_iter_sizeof) (void)
511 return genhash_iter_sizeof();
514 /****************************************************************************
515 Initialize an iterator.
516 ****************************************************************************/
517 static inline struct iterator *
518 SPECHASH_FOO(_hash_iter_init) (SPECHASH_ITER *iter,
519 const SPECHASH_HASH *tthis)
521 return genhash_iter_init((struct genhash_iter *) iter,
522 (const struct genhash *) tthis);
525 /****************************************************************************
526 Initialize a key iterator.
527 ****************************************************************************/
528 static inline struct iterator *
529 SPECHASH_FOO(_hash_key_iter_init) (SPECHASH_ITER *iter,
530 const SPECHASH_HASH *tthis)
532 return genhash_key_iter_init((struct genhash_iter *) iter,
533 (const struct genhash *) tthis);
536 /****************************************************************************
537 Initialize a value iterator.
538 ****************************************************************************/
539 static inline struct iterator *
540 SPECHASH_FOO(_hash_value_iter_init) (SPECHASH_ITER *iter,
541 const SPECHASH_HASH *tthis)
543 return genhash_value_iter_init((struct genhash_iter *) iter,
544 (const struct genhash *) tthis);
547 #undef SPECHASH_TAG
548 #undef SPECHASH_KEY_TYPE
549 #undef SPECHASH_DATA_TYPE
550 #undef SPECHASH_KEY_VAL
551 #undef SPECHASH_KEY_COMP
552 #undef SPECHASH_KEY_COPY
553 #undef SPECHASH_KEY_FREE
554 #undef SPECHASH_DATA_COMP
555 #undef SPECHASH_DATA_COPY
556 #undef SPECHASH_DATA_FREE
557 #undef SPECHASH_KEY_TO_PTR
558 #undef SPECHASH_PTR_TO_KEY
559 #undef SPECHASH_DATA_TO_PTR
560 #undef SPECHASH_PTR_TO_DATA
561 #undef SPECHASH_PASTE_
562 #undef SPECHASH_PASTE
563 #undef SPECHASH_HASH
564 #undef SPECHASH_ITER
565 #undef SPECHASH_FOO
568 /* Base macros that the users can specialize. */
569 #ifndef FC__SPECHASH_H /* Defines this only once, no multiple inclusions. */
570 #define FC__SPECHASH_H
572 /* Spechash value iterator.
574 * TYPE_data - The real type of the data in the genhash.
575 * ARG_ht - The genhash to iterate.
576 * NAME_data - The name of the data iterator (defined inside the macro). */
577 #define TYPED_HASH_DATA_ITERATE(TYPE_data, ARG_ht, NAME_data) \
578 generic_iterate(struct genhash_iter, TYPE_data, NAME_data, \
579 genhash_iter_sizeof, genhash_value_iter_init, \
580 (const struct genhash *) (ARG_ht))
582 /* Balance for above: */
583 #define HASH_DATA_ITERATE_END generic_iterate_end
585 /* Spechash key iterator.
587 * TYPE_key - The real type of the key in the genhash.
588 * ARG_ht - The genhash to iterate.
589 * NAME_key - The name of the key iterator (defined inside the macro). */
590 #define TYPED_HASH_KEYS_ITERATE(TYPE_key, ARG_ht, NAME_key) \
591 generic_iterate(struct genhash_iter, TYPE_key, NAME_key, \
592 genhash_iter_sizeof, genhash_key_iter_init, \
593 (const struct genhash *) (ARG_ht))
595 /* Balance for above: */
596 #define HASH_KEYS_ITERATE_END \
598 } while (FALSE);
600 /* Spechash key and values iterator.
602 * TYPE_key - The real type of the key in the genhash.
603 * TYPE_data - The real type of the key in the genhash.
604 * ARG_ht - The genhash to iterate.
605 * NAME_key - The name of the key iterator (defined inside the macro).
606 * NAME_data - The name of the data iterator (defined inside the macro). */
607 #define TYPED_HASH_ITERATE(TYPE_key, TYPE_data, ARG_ht, NAME_key, NAME_data)\
608 genhash_iterate((const struct genhash *) (ARG_ht), MY_iter) { \
609 TYPE_key NAME_key = (TYPE_key) genhash_iter_key(MY_iter); \
610 TYPE_data NAME_data = (TYPE_data) genhash_iter_value(MY_iter);
612 /* Balance for above: */
613 #define HASH_ITERATE_END \
614 } genhash_iterate_end;
616 #endif /* FC__SPECHASH_H */
618 /* This is after #endif FC__SPECHASH_H on purpose.
619 extern "C" portion begins well before latter part of the header
620 is guarded against multiple inclusions. */
621 #ifdef __cplusplus
623 #endif /* __cplusplus */