deba@627: #ifndef ARRAY_MAP_H deba@627: #define ARRAY_MAP_H deba@627: deba@627: #include deba@627: deba@627: deba@627: #include deba@627: using namespace std; deba@627: deba@627: namespace hugo { deba@627: deba@674: template class ArrayMapFactory { deba@674: deba@674: public: deba@674: deba@674: typedef typename MapRegistry::Graph Graph; deba@674: typedef typename MapRegistry::Key Key; deba@674: typedef typename MapRegistry::KeyIt KeyIt; deba@674: deba@674: typedef typename MapRegistry::MapBase MapBase; deba@674: deba@674: template > deba@674: class Map : public MapBase { deba@674: deba@627: public: deba@674: deba@674: typedef V Value; deba@674: typedef A Allocator; deba@627: deba@627: deba@674: Map() : values(0), capacity(0) {} deba@627: deba@674: Map(Graph& g, MapRegistry& r) : MapBase(g, r) { deba@674: int max_id = -1; deba@674: for (KeyIt it(*graph); graph->valid(it); graph->next(it)) { deba@674: int id = graph->id(it); deba@674: if (id > max_id) { deba@674: max_id = id; deba@674: } deba@674: } deba@674: if (max_id == -1) { deba@674: capacity = 0; deba@674: values = 0; deba@674: return; deba@674: } deba@674: capacity = 1; deba@674: while (capacity <= max_id) { deba@674: capacity <<= 1; deba@674: } deba@674: values = allocator.allocate(capacity); deba@674: for (KeyIt it(*graph); graph->valid(it); graph->next(it)) { deba@674: int id = graph->id(it); deba@674: allocator.construct(&(values[id]), Value()); deba@674: } deba@674: } deba@674: deba@674: Map(const Map& copy) : MapBase(*copy.graph, *copy.registry) { deba@674: capacity = copy.capacity; deba@674: values = allocator.allocate(capacity); deba@674: for (KeyIt it(*graph); graph->valid(it); graph->next(it)) { deba@674: int id = graph->id(it); deba@674: allocator.construct(&(values[id]), copy.values[id]); deba@674: } deba@674: } deba@627: deba@674: virtual ~Map() { deba@674: destroy(); deba@674: allocator.deallocate(values, capacity); deba@674: } deba@627: deba@627: deba@674: Value& operator[](const Key& key) { deba@674: int id = graph->id(key); deba@674: return values[id]; deba@674: } deba@627: deba@674: const Value& operator[](const Key& key) const { deba@674: int id = graph->id(key); deba@674: return values[id]; deba@674: } deba@627: deba@674: const Value& get(const Key& key) const { deba@674: int id = graph->id(key); deba@674: return values[id]; deba@674: } deba@627: deba@674: void set(const Key& key, const Value& val) { deba@674: int id = graph->id(key); deba@674: values[id] = val; deba@674: } deba@627: deba@674: void add(const Key& key) { deba@674: int id = graph->id(key); deba@674: if (id >= capacity) { deba@674: int new_capacity = (capacity == 0 ? 1 : capacity); deba@674: while (new_capacity <= id) { deba@674: new_capacity <<= 1; deba@674: } deba@674: Value* new_values = allocator.allocate(new_capacity);; deba@674: for (KeyIt it(*graph); graph->valid(it); graph->next(it)) { deba@674: int jd = graph->id(it); deba@674: if (id != jd) { deba@674: allocator.construct(&(new_values[jd]), values[jd]); deba@674: allocator.destroy(&(values[jd])); deba@674: } deba@674: } deba@674: if (capacity != 0) allocator.deallocate(values, capacity); deba@674: values = new_values; deba@674: capacity = new_capacity; deba@674: } deba@674: allocator.construct(&(values[id]), Value()); deba@674: } deba@627: deba@674: void erase(const Key& key) { deba@674: int id = graph->id(key); deba@674: allocator.destroy(&(values[id])); deba@674: } deba@627: deba@674: private: deba@674: int capacity; deba@674: Value* values; deba@674: Allocator allocator; deba@674: }; deba@674: }; deba@627: } deba@627: deba@627: #endif