deba@627: #ifndef ARRAY_MAP_H
deba@627: #define ARRAY_MAP_H
deba@627: 
deba@627: #include <memory>
deba@627: 
deba@627: #include "map_base.h"
deba@627: 
deba@627: #include <iostream>
deba@627: using namespace std;
deba@627: 
deba@627: namespace hugo {
deba@627: 	
deba@627: 	template <typename G, typename K, typename KIt>
deba@627: 	class ArrayMapFactory {
deba@627: 	
deba@627: 	
deba@627: 	public:
deba@627: 		
deba@627: 		typedef G Graph;
deba@627: 		typedef K Key;
deba@627: 		typedef KIt KeyIt;
deba@627: 		
deba@627: 		template <typename V, typename A = allocator<V> > 
deba@627: 		class Map : public MapBase<G, K, KIt> {
deba@627: 		public:
deba@627: 			typedef V Value;
deba@627: 			typedef typename _Alloc_traits<V, A>::_Alloc_type _Alloc_type;
deba@627: 
deba@627: 	
deba@627: 			Map() : values(0), capacity(0) {}
deba@627: 			
deba@627: 			Map(Graph& g, MapRegistry<G, K, KIt>& r) 
deba@627: 				: MapBase<G, K, KIt>(g, r) {
deba@627: 				int max_id = -1;
deba@627: 				for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@627: 					int id = graph->id(it);
deba@627: 					if (id > max_id) {
deba@627: 						max_id = id;
deba@627: 					}				
deba@627: 				}
deba@627: 				if (max_id == -1) {
deba@627: 					capacity = 0;
deba@627: 					values = 0;
deba@627: 					return;
deba@627: 				}
deba@627: 				int capacity = 1;
deba@627: 				while (capacity <= max_id) {
deba@627: 					capacity <<= 1;
deba@627: 				}
deba@627: 				Value* values = reinterpret_cast<Value*>(new char[capacity*sizeof(Value)]);
deba@627: 				for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@627: 					int id = graph->id(it);
deba@627: 					new(&(values[id])) Value();
deba@627: 				}								
deba@627: 				cerr << capacity << endl;	
deba@627: 			}
deba@627: 				
deba@627: 			virtual ~Map() {
deba@627: 				destroy();
deba@627: 				delete[] reinterpret_cast<char*>(values);
deba@627: 				values = 0;
deba@627: 				capacity = 0;
deba@627: 			}
deba@627: 	
deba@627: 	
deba@627: 			Value& operator[](const K& key) {
deba@627: 				int id = graph->id(key);
deba@627: 				return values[id];
deba@627: 			} 
deba@627: 		
deba@627: 			const Value& operator[](const K& key) const {
deba@627: 				int id = graph->id(key);
deba@627: 				return values[id];
deba@627: 			}
deba@627: 	
deba@627: 			const Value& get(const K& key) const {
deba@627: 				int id = graph->id(key);
deba@627: 				return values[id];
deba@627: 			} 
deba@627: 		
deba@627: 			void set(const K& key, const Value& val) {
deba@627: 				int id = graph->id(key);
deba@627: 				values[id] = val;
deba@627: 			}
deba@627: 		
deba@627: 			void add(const K& key) {
deba@627: 				cerr << capacity << endl;
deba@627: 				int id = graph->id(key);
deba@627: 				if (id >= capacity) {
deba@627: 					int new_capacity = (capacity == 0 ? 1 : capacity);
deba@627: 					while (new_capacity <= id) {
deba@627: 						new_capacity <<= 1;
deba@627: 					}
deba@627: 					Value* new_values = reinterpret_cast<Value*>(new char[new_capacity*sizeof(Value)]);;
deba@627: 					for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@627: 						int jd = graph->id(it);
deba@627: 						if (id != jd) {
deba@627: 							new(&(new_values[jd])) Value(values[jd]);
deba@627: 						}
deba@627: 					}
deba@627: 					if (capacity != 0) delete[] reinterpret_cast<char *>(values);
deba@627: 					values = new_values;
deba@627: 					capacity = new_capacity;
deba@627: 				}
deba@627: 				cerr << id << ' ' << capacity << endl;
deba@627: 				new(&(values[id])) Value();
deba@627: 			}
deba@627: 		
deba@627: 			void erase(const K& key) {
deba@627: 				int id = graph->id(key);
deba@627: 				values[id].~Value();
deba@627: 			}
deba@627: 	
deba@627: 		private:
deba@627: 			int capacity;
deba@627: 			Value* values;
deba@627: 								
deba@627: 		};
deba@627: 		
deba@627: 	};
deba@627: }
deba@627: 
deba@627: #endif