#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <assert.h>
struct string_to_uint_map;
#ifdef __cplusplus
extern "C" {
#endif
struct hash_table;
typedef unsigned (*hash_func_t)(const void *key);
typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
extern struct hash_table *hash_table_ctor(unsigned num_buckets,
hash_func_t hash, hash_compare_func_t compare);
extern void hash_table_dtor(struct hash_table *ht);
extern void hash_table_clear(struct hash_table *ht);
extern void *hash_table_find(struct hash_table *ht, const void *key);
extern void hash_table_insert(struct hash_table *ht, void *data,
const void *key);
extern bool hash_table_replace(struct hash_table *ht, void *data,
const void *key);
extern void hash_table_remove(struct hash_table *ht, const void *key);
extern unsigned hash_table_string_hash(const void *key);
#define hash_table_string_compare ((hash_compare_func_t) strcmp)
unsigned
hash_table_pointer_hash(const void *key);
int
hash_table_pointer_compare(const void *key1, const void *key2);
void
hash_table_call_foreach(struct hash_table *ht,
void (*callback)(const void *key,
void *data,
void *closure),
void *closure);
struct string_to_uint_map *
string_to_uint_map_ctor();
void
string_to_uint_map_dtor(struct string_to_uint_map *);
#ifdef __cplusplus
}
struct string_to_uint_map {
public:
string_to_uint_map()
{
this->ht = hash_table_ctor(0, hash_table_string_hash,
hash_table_string_compare);
}
~string_to_uint_map()
{
hash_table_call_foreach(this->ht, delete_key, NULL);
hash_table_dtor(this->ht);
}
void clear()
{
hash_table_call_foreach(this->ht, delete_key, NULL);
hash_table_clear(this->ht);
}
bool get(unsigned &value, const char *key)
{
const intptr_t v =
(intptr_t) hash_table_find(this->ht, (const void *) key);
if (v == 0)
return false;
value = (unsigned)(v - 1);
return true;
}
void put(unsigned value, const char *key)
{
assert(value != UINT_MAX);
char *dup_key = strdup(key);
bool result = hash_table_replace(this->ht,
(void *) (intptr_t) (value + 1),
dup_key);
if (result)
free(dup_key);
}
private:
static void delete_key(const void *key, void *data, void *closure)
{
(void) data;
(void) closure;
free((char *)key);
}
struct hash_table *ht;
};
#endif
#endif