diff options
Diffstat (limited to 'include/libHX/map.h')
-rw-r--r-- | include/libHX/map.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/include/libHX/map.h b/include/libHX/map.h new file mode 100644 index 0000000..ecbf703 --- /dev/null +++ b/include/libHX/map.h @@ -0,0 +1,140 @@ +#ifndef _LIBHX_MAP_H +#define _LIBHX_MAP_H 1 + +#ifdef __cplusplus +# include <cstddef> +#else +# include <stdbool.h> +# include <stddef.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Abstract: + * %HXMAPT_DEFAULT: whatever is fast and maps k-v, without preference + * %HXMAPT_ORDERED: anything ordered, no further preference + * + * Specific: + * %HXMAPT_HASH: map based on hash + * %HXMAPT_RBTREE: map based on red-black binary tree + */ +enum HXmap_type { + HXMAPT_HASH = 1, + HXMAPT_RBTREE, + + /* aliases - assignments may change */ + HXMAPT_DEFAULT = HXMAPT_HASH, + HXMAPT_ORDERED = HXMAPT_RBTREE, +}; + +/** + * Flags changable at runtime: + * %HXMAP_NOREPLACE: Calling HXmap_add() for an already existing key will + * throw an error (no-overwrite semantics) + * + * Initialization-time flags only: + * %HXMAP_NONE: mnemonic for no flags + * %HXMAP_SINGULAR: Instead of an associative map, provide a set + * %HXMAP_SKEY: Key will be a C-style string (sets ops->k_*) + * %HXMAP_CKEY: Make a copy of the key on HXmap_add + * %HXMAP_SDATA: Data will be a C-style string (presets ops->d_*) + * %HXMAP_CDATA: Make a copy of the data on HXmap_add + */ +enum { + HXMAP_NONE = 0, + HXMAP_NOREPLACE = 1 << 0, + HXMAP_SINGULAR = 1 << 1, + HXMAP_SKEY = 1 << 2, + HXMAP_CKEY = 1 << 3, + HXMAP_SDATA = 1 << 4, + HXMAP_CDATA = 1 << 5, + + HXMAP_SCKEY = HXMAP_SKEY | HXMAP_CKEY, + HXMAP_SCDATA = HXMAP_SDATA | HXMAP_CDATA, +}; + +/** + * Flags for the traverser + * %HXMAP_NOFLAGS: Mnemonic for no flags + * %HXMAP_DTRAV: Support deletion of elements while traversing + */ +enum { + HXMAP_NOFLAGS = 0, + HXMAP_DTRAV = 1 << 0, +}; + +struct HXmap_trav; + +/** + * @items: number of items in the map + * @flags: flags for this map + */ +struct HXmap { + unsigned int items, flags; +}; + +struct HXmap_ops { + /* k_compare: the size argument is needed for memcmp. */ + int (*k_compare)(const void *, const void *, size_t); + void *(*k_clone)(const void *, size_t); + void (*k_free)(void *); + void *(*d_clone)(const void *, size_t); + void (*d_free)(void *); + unsigned long (*k_hash)(const void *, size_t); +}; + +struct HXmap_node { + union { + void *key; + const char *const skey; + }; + union { + void *data; + char *sdata; + }; +}; + +extern struct HXmap *HXmap_init(enum HXmap_type, unsigned int); +extern struct HXmap *HXmap_init5(enum HXmap_type, unsigned int, + const struct HXmap_ops *, size_t, size_t); + +extern int HXmap_add(struct HXmap *, const void *, const void *); +extern const struct HXmap_node *HXmap_find(const struct HXmap *, const void *); +extern void *HXmap_get(const struct HXmap *, const void *); +extern void *HXmap_del(struct HXmap *, const void *); +extern struct HXmap_node *HXmap_keysvalues(const struct HXmap *); +extern struct HXmap_trav *HXmap_travinit(const struct HXmap *, unsigned int); +extern const struct HXmap_node *HXmap_traverse(struct HXmap_trav *); +extern void HXmap_travfree(struct HXmap_trav *); +extern void HXmap_qfe(const struct HXmap *, + bool (*)(const struct HXmap_node *, void *), void *); +extern void HXmap_free(struct HXmap *); + +extern unsigned long HXhash_jlookup3(const void *, size_t); +extern unsigned long HXhash_jlookup3s(const void *, size_t); +extern unsigned long HXhash_djb2(const void *, size_t); + +#ifdef __cplusplus +} /* extern "C" */ + +extern "C++" { + +template<typename type> static __inline__ type +HXmap_get(const struct HXmap *map, const void *key) +{ + return reinterpret_cast<type>(HXmap_get(map, key)); +} + +template<typename type> static __inline__ type +HXmap_del(struct HXmap *map, const void *key) +{ + return reinterpret_cast<type>(HXmap_del(map, key)); +} + +} +#endif + +#endif /* _LIBHX_MAP_H */ |