]> git.ozlabs.org Git - ccan/blob - ccan/htable/htable_type.h
af9da1b22692baa0331241a0bde56a84899a6165
[ccan] / ccan / htable / htable_type.h
1 /* Licensed under LGPLv2+ - see LICENSE file for details */
2 #ifndef CCAN_HTABLE_TYPE_H
3 #define CCAN_HTABLE_TYPE_H
4 #include <ccan/htable/htable.h>
5 #include "config.h"
6
7 /**
8  * HTABLE_DEFINE_TYPE - create a set of htable ops for a type
9  * @type: a type whose pointers will be values in the hash.
10  * @keyof: a function/macro to extract a key from a @type element.
11  * @hashfn: a hash function for a @key
12  * @cmpfn: a comparison function for two keyof()s.
13  * @name: a name for all the functions to define (of form htable_<name>_*)
14  *
15  * NULL values may not be placed into the hash table.
16  *
17  * The following wrapper functions are defined; each one is a
18  * simplified version of the htable.h equivalent:
19  *
20  *      // Creating and freeing.
21  *      struct htable_@name *htable_@name_new(void);
22  *      void htable_@name_free(const struct htable_@name *ht);
23  *
24  *      // Add, delete and find.
25  *      bool htable_@name_add(struct htable_@name *ht, const type *e);
26  *      bool htable_@name_del(struct htable_@name *ht, const type *e);
27  *      bool htable_@name_delkey(struct htable_@name *ht, const ktype *k);
28  *      type *htable_@name_get(const struct htable_@name *ht, const ktype *k);
29  *
30  *      // Iteration.
31  *      struct htable_@name_iter;
32  *      type *htable_@name_first(const struct htable_@name *ht,
33  *                               struct htable_@name_iter *i);
34  *      type *htable_@name_next(const struct htable_@name *ht,
35  *                              struct htable_@name_iter *i);
36  */
37 #define HTABLE_DEFINE_TYPE(type, keyof, hashfn, cmpfn, name)            \
38 struct htable_##name;                                                   \
39 struct htable_##name##_iter { struct htable_iter i; };                  \
40 static inline size_t htable_##name##_hash(const void *elem, void *priv) \
41 {                                                                       \
42         return hashfn(keyof((const type *)elem));                       \
43 }                                                                       \
44 static inline struct htable_##name *htable_##name##_new(void)           \
45 {                                                                       \
46         return (struct htable_##name *)htable_new(htable_##name##_hash, \
47                                                   NULL);                \
48 }                                                                       \
49 static inline void htable_##name##_free(const struct htable_##name *ht) \
50 {                                                                       \
51         htable_free((const struct htable *)ht);                         \
52 }                                                                       \
53 static inline bool htable_##name##_add(struct htable_##name *ht,        \
54                                        const type *elem)                \
55 {                                                                       \
56         return htable_add((struct htable *)ht, hashfn(keyof(elem)), elem); \
57 }                                                                       \
58 static inline bool htable_##name##_del(const struct htable_##name *ht,  \
59                                        const type *elem)                \
60 {                                                                       \
61         return htable_del((struct htable *)ht, hashfn(keyof(elem)), elem); \
62 }                                                                       \
63 static inline type *htable_##name##_get(const struct htable_##name *ht, \
64                                         const HTABLE_KTYPE(keyof) k)    \
65 {                                                                       \
66         /* Typecheck for cmpfn */                                       \
67         (void)sizeof(cmpfn((const type *)NULL,                          \
68                            keyof((const type *)NULL)));                 \
69         return (type *)htable_get((const struct htable *)ht,            \
70                                   hashfn(k),                            \
71                                   (bool (*)(const void *, void *))(cmpfn), \
72                                   k);                                   \
73 }                                                                       \
74 static inline bool htable_##name##_delkey(struct htable_##name *ht,     \
75                                           const HTABLE_KTYPE(keyof) k) \
76 {                                                                       \
77         type *elem = htable_##name##_get(ht, k);                        \
78         if (elem)                                                       \
79                 return htable_##name##_del(ht, elem);                   \
80         return false;                                                   \
81 }                                                                       \
82 static inline type *htable_##name##_first(const struct htable_##name *ht, \
83                                           struct htable_##name##_iter *iter) \
84 {                                                                       \
85         return htable_first((const struct htable *)ht, &iter->i);       \
86 }                                                                       \
87 static inline type *htable_##name##_next(const struct htable_##name *ht, \
88                                          struct htable_##name##_iter *iter) \
89 {                                                                       \
90         return htable_next((const struct htable *)ht, &iter->i);        \
91 }
92
93 #if HAVE_TYPEOF
94 #define HTABLE_KTYPE(keyof) typeof(keyof(NULL))
95 #else
96 #define HTABLE_KTYPE(keyof) void *
97 #endif
98 #endif /* CCAN_HTABLE_TYPE_H */