X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Fhtable%2Fhtable_type.h;h=14011676903807fed252318ef5884b55f14e9556;hb=b7cb7dfdf27243696183698b2f82522003cc1216;hp=61535c2c665c43fa611f5b995205e9fccd94f648;hpb=15966998bbeaea92e4e1b1c9f067a4142f51f680;p=ccan diff --git a/ccan/htable/htable_type.h b/ccan/htable/htable_type.h index 61535c2c..14011676 100644 --- a/ccan/htable/htable_type.h +++ b/ccan/htable/htable_type.h @@ -21,8 +21,9 @@ * * It also defines initialization and freeing functions: * void _init(struct *); - * void _init_sized(struct *, size_t); + * bool _init_sized(struct *, size_t); * void _clear(struct *); + * bool _copy(struct *dst, const struct *src); * * Add function only fails if we run out of memory: * bool _add(struct *ht, const *e); @@ -43,6 +44,7 @@ * Iteration over hashtable is also supported: * type *_first(const struct *ht, struct _iter *i); * type *_next(const struct *ht, struct _iter *i); + * type *_prev(const struct *ht, struct _iter *i); * * It's currently safe to iterate over a changing hashtable, but you might * miss an element. Iteration isn't very efficient, either. @@ -62,15 +64,20 @@ { \ htable_init(&ht->raw, name##_hash, NULL); \ } \ - static inline UNNEEDED void name##_init_sized(struct name *ht, \ + static inline UNNEEDED bool name##_init_sized(struct name *ht, \ size_t s) \ { \ - htable_init_sized(&ht->raw, name##_hash, NULL, s); \ + return htable_init_sized(&ht->raw, name##_hash, NULL, s); \ } \ static inline UNNEEDED void name##_clear(struct name *ht) \ { \ htable_clear(&ht->raw); \ } \ + static inline UNNEEDED bool name##_copy(struct name *dst, \ + const struct name *src) \ + { \ + return htable_copy(&dst->raw, &src->raw); \ + } \ static inline bool name##_add(struct name *ht, const type *elem) \ { \ return htable_add(&ht->raw, hashfn(keyof(elem)), elem); \ @@ -81,18 +88,22 @@ return htable_del(&ht->raw, hashfn(keyof(elem)), elem); \ } \ static inline UNNEEDED type *name##_get(const struct name *ht, \ - const HTABLE_KTYPE(keyof) k) \ + const HTABLE_KTYPE(keyof, type) k) \ { \ - /* Typecheck for eqfn */ \ - (void)sizeof(eqfn((const type *)NULL, \ - keyof((const type *)NULL))); \ - return htable_get(&ht->raw, \ - hashfn(k), \ - (bool (*)(const void *, void *))(eqfn), \ - k); \ + struct htable_iter i; \ + size_t h = hashfn(k); \ + void *c; \ + \ + for (c = htable_firstval(&ht->raw,&i,h); \ + c; \ + c = htable_nextval(&ht->raw,&i,h)) { \ + if (eqfn(c, k)) \ + return c; \ + } \ + return NULL; \ } \ static inline UNNEEDED type *name##_getmatch_(const struct name *ht, \ - const HTABLE_KTYPE(keyof) k, \ + const HTABLE_KTYPE(keyof, type) k, \ size_t h, \ type *v, \ struct name##_iter *iter) \ @@ -105,7 +116,7 @@ return v; \ } \ static inline UNNEEDED type *name##_getfirst(const struct name *ht, \ - const HTABLE_KTYPE(keyof) k, \ + const HTABLE_KTYPE(keyof, type) k, \ struct name##_iter *iter) \ { \ size_t h = hashfn(k); \ @@ -113,7 +124,7 @@ return name##_getmatch_(ht, k, h, v, iter); \ } \ static inline UNNEEDED type *name##_getnext(const struct name *ht, \ - const HTABLE_KTYPE(keyof) k, \ + const HTABLE_KTYPE(keyof, type) k, \ struct name##_iter *iter) \ { \ size_t h = hashfn(k); \ @@ -121,7 +132,7 @@ return name##_getmatch_(ht, k, h, v, iter); \ } \ static inline UNNEEDED bool name##_delkey(struct name *ht, \ - const HTABLE_KTYPE(keyof) k) \ + const HTABLE_KTYPE(keyof, type) k) \ { \ type *elem = name##_get(ht, k); \ if (elem) \ @@ -137,11 +148,19 @@ struct name##_iter *iter) \ { \ return htable_next(&ht->raw, &iter->i); \ + } \ + static inline UNNEEDED type *name##_prev(const struct name *ht, \ + struct name##_iter *iter) \ + { \ + return htable_prev(&ht->raw, &iter->i); \ } #if HAVE_TYPEOF -#define HTABLE_KTYPE(keyof) typeof(keyof(NULL)) +#define HTABLE_KTYPE(keyof, type) typeof(keyof((const type *)NULL)) #else -#define HTABLE_KTYPE(keyof) void * +/* Assumes keys are a pointer: if not, override. */ +#ifndef HTABLE_KTYPE +#define HTABLE_KTYPE(keyof, type) void * +#endif #endif #endif /* CCAN_HTABLE_TYPE_H */