#ifndef HASHMAP_H #define HASHMAP_H #include #include namespace opp { template struct Hash {}; template<> struct Hash { unsigned operator()(const int & k) { return k; } }; template<> struct Hash { unsigned operator()(const string & k) { const char * cp = k.begin(); if (cp) { unsigned hash = 0; while (*cp) hash = hash * 17 + *cp++; return hash; } else return 0; } }; template struct hashpair { K key; T value; unsigned hash; hashpair(void) {} hashpair(const K & k, unsigned h) : key(k), hash(h) {} hashpair(const hashpair & p) : key(p.key), value(p.value), hash(p.hash) {} }; template class hashmap { public: hashmap(void); ~hashmap(void); typedef hashpair N; typedef list_iterator I; T & at(const K & key); void insert(const K & key, const T & value); void erase(const K & key); list_iterator > erase(list_iterator > iter); I begin(void); I end(void); I find(const K & key); private: unsigned mapsize; unsigned size; list list; I * map; }; template hashmap::hashmap(void) : mapsize(0), size(0), map(nullptr) {} template hashmap::~hashmap(void) { delete[] map; } template hashmap::I hashmap::begin(void) { return list.begin(); } template hashmap::I hashmap::end(void) { return list.end(); } template T & hashmap::at(const K & key) { if (mapsize == 0) { mapsize = 16; map = new I[16]; for(unsigned i=0; i<16; i++) map[i] = list.end(); } unsigned m = mapsize - 1; unsigned h = Hash()(key); unsigned hi = h & m; I p = map[hi]; while (p != list.end() && (p->hash & m) == hi) { if (p->key == key) return p->value; p++; } p = list.insert(map[hi], N(key, h)); map[hi] = p; return p->value; } template hashmap::I hashmap::find(const K & key) { if (mapsize) { unsigned m = mapsize - 1; unsigned h = Hash()(key); unsigned hi = h & m; I p = map[hi]; while (p != list.end() && (p->hash & m) == hi) { if (p->key == key) return p; p++; } } return list.end(); } template void hashmap::insert(const K & key, const T & value) { this->at(key) = value; } template void hashmap::erase(const K & key) { erase(find(key)); } template list_iterator > hashmap::erase(list_iterator > iter) { if (iter != list.end()) { unsigned hi = iter->hash & (mapsize - 1); bool first = iter == map[hi]; iter = list.erase(iter); if (first) map[hi] = iter; } return iter; } } #endif