summaryrefslogtreecommitdiff
path: root/include/libHX/map.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/libHX/map.h')
-rw-r--r--include/libHX/map.h140
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 */