| deba@703 |      1 | // -*- c++ -*-
 | 
| deba@627 |      2 | #ifndef ARRAY_MAP_H
 | 
| deba@627 |      3 | #define ARRAY_MAP_H
 | 
| deba@627 |      4 | 
 | 
| deba@627 |      5 | #include <memory>
 | 
| deba@627 |      6 | 
 | 
| deba@703 |      7 | #include "extended_pair.h"
 | 
| deba@627 |      8 | 
 | 
| alpar@921 |      9 | namespace lemon {
 | 
| deba@627 |     10 | 	
 | 
| deba@674 |     11 |   template <typename MapRegistry> class ArrayMapFactory {
 | 
| deba@674 |     12 | 		
 | 
| deba@674 |     13 |   public:
 | 
| deba@674 |     14 | 		
 | 
| deba@674 |     15 |     typedef typename MapRegistry::Graph Graph;
 | 
| deba@674 |     16 |     typedef typename MapRegistry::Key Key;
 | 
| deba@674 |     17 |     typedef typename MapRegistry::KeyIt KeyIt;
 | 
| deba@674 |     18 | 
 | 
| deba@674 |     19 |     typedef typename MapRegistry::MapBase MapBase;
 | 
| deba@674 |     20 | 		
 | 
| deba@703 |     21 |     template <typename V, typename A = std::allocator<V> > 
 | 
| deba@703 |     22 |     class Map : public MapBase {
 | 
| deba@674 |     23 |     
 | 
| deba@702 |     24 |       public:
 | 
| deba@674 |     25 | 
 | 
| deba@702 |     26 |       typedef V Value;
 | 
| deba@702 |     27 |       typedef A Allocator;
 | 
| deba@627 |     28 | 
 | 
| deba@627 |     29 | 	
 | 
| deba@702 |     30 |       Map() : values(0), capacity(0) {}
 | 
| deba@627 |     31 | 			
 | 
| deba@702 |     32 |       Map(const Graph& g, MapRegistry& r) : MapBase(g, r) {
 | 
| deba@703 |     33 | 	allocate_memory();
 | 
| deba@702 |     34 | 	for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     35 | 	  int id = getGraph()->id(it);
 | 
| deba@702 |     36 | 	  allocator.construct(&(values[id]), Value());
 | 
| deba@702 |     37 | 	}								
 | 
| deba@702 |     38 |       }
 | 
| deba@674 |     39 | 
 | 
| deba@702 |     40 |       Map(const Graph& g, MapRegistry& r, const Value& v) : MapBase(g, r) {
 | 
| deba@703 |     41 | 	allocate_memory();
 | 
| deba@702 |     42 | 	for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     43 | 	  int id = getGraph()->id(it);
 | 
| deba@702 |     44 | 	  allocator.construct(&(values[id]), v);
 | 
| deba@702 |     45 | 	}								
 | 
| deba@702 |     46 |       }
 | 
| deba@702 |     47 | 
 | 
| deba@702 |     48 |       Map(const Map& copy) : MapBase(*copy.graph, *copy.registry) {
 | 
| deba@702 |     49 | 	capacity = copy.capacity;
 | 
| deba@702 |     50 | 	if (capacity == 0) return;
 | 
| deba@702 |     51 | 	values = allocator.allocate(capacity);
 | 
| deba@702 |     52 | 	for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     53 | 	  int id = getGraph()->id(it);
 | 
| deba@702 |     54 | 	  allocator.construct(&(values[id]), copy.values[id]);
 | 
| deba@702 |     55 | 	}
 | 
| deba@702 |     56 |       }
 | 
| deba@702 |     57 | 
 | 
| deba@703 |     58 |       template <typename CMap> Map(const CMap& copy) 
 | 
| deba@703 |     59 | 	: capacity(0), values(0), MapBase(copy) {
 | 
| deba@702 |     60 | 	if (getGraph()) {
 | 
| deba@703 |     61 | 	  allocate_memory();
 | 
| deba@702 |     62 | 	  for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     63 | 	    set(it, copy[it]);
 | 
| deba@674 |     64 | 	  }
 | 
| deba@674 |     65 | 	}
 | 
| deba@702 |     66 |       }
 | 
| deba@702 |     67 | 
 | 
| deba@702 |     68 |       Map& operator=(const Map& copy) {
 | 
| deba@702 |     69 | 	if (© == this) return;
 | 
| deba@702 |     70 | 	if (capacity != 0) {
 | 
| deba@674 |     71 | 	  destroy();
 | 
| deba@674 |     72 | 	  allocator.deallocate(values, capacity);
 | 
| deba@674 |     73 | 	}
 | 
| deba@702 |     74 | 	capacity = copy.capacity;
 | 
| deba@702 |     75 | 	if (capacity == 0) return;
 | 
| deba@702 |     76 | 	values = allocator.allocate(capacity);
 | 
| deba@702 |     77 | 	for (KeyIt it(getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     78 | 	  int id = getGraph()->id(it);
 | 
| deba@702 |     79 | 	  allocator.construct(&(values[id]), copy.values[id]);
 | 
| deba@702 |     80 | 	}
 | 
| deba@702 |     81 |       }
 | 
| deba@702 |     82 | 
 | 
| deba@702 |     83 |       template <typename CMap> Map& operator=(const CMap& copy) {
 | 
| deba@702 |     84 | 	if (getGraph()) {
 | 
| deba@702 |     85 | 	  destroy();
 | 
| deba@702 |     86 | 	} 
 | 
| deba@702 |     87 | 	this->MapBase::operator=(copy);
 | 
| deba@702 |     88 | 	if (getGraph()) {
 | 
| deba@703 |     89 | 	  allocate_memory();
 | 
| deba@702 |     90 | 	  for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |     91 | 	    set(it, copy[it]);
 | 
| deba@702 |     92 | 	  }
 | 
| deba@702 |     93 | 	}
 | 
| deba@702 |     94 |       }
 | 
| deba@702 |     95 | 				
 | 
| deba@702 |     96 |       virtual ~Map() {
 | 
| deba@702 |     97 | 	if (capacity != 0) {
 | 
| deba@702 |     98 | 	  destroy();
 | 
| deba@702 |     99 | 	  allocator.deallocate(values, capacity);
 | 
| deba@702 |    100 | 	}
 | 
| deba@702 |    101 |       }
 | 
| deba@627 |    102 | 	
 | 
| deba@627 |    103 | 	
 | 
| deba@702 |    104 |       Value& operator[](const Key& key) {
 | 
| deba@702 |    105 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    106 | 	return values[id];
 | 
| deba@702 |    107 |       } 
 | 
| deba@627 |    108 | 		
 | 
| deba@702 |    109 |       const Value& operator[](const Key& key) const {
 | 
| deba@702 |    110 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    111 | 	return values[id];
 | 
| deba@702 |    112 |       }
 | 
| deba@702 |    113 | 	
 | 
| deba@702 |    114 |       const Value& get(const Key& key) const {
 | 
| deba@702 |    115 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    116 | 	return values[id];
 | 
| deba@702 |    117 |       } 
 | 
| deba@702 |    118 | 		
 | 
| deba@702 |    119 |       void set(const Key& key, const Value& val) {
 | 
| deba@702 |    120 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    121 | 	values[id] = val;
 | 
| deba@702 |    122 |       }
 | 
| deba@702 |    123 | 		
 | 
| deba@702 |    124 |       void add(const Key& key) {
 | 
| deba@702 |    125 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    126 | 	if (id >= capacity) {
 | 
| deba@702 |    127 | 	  int new_capacity = (capacity == 0 ? 1 : capacity);
 | 
| deba@702 |    128 | 	  while (new_capacity <= id) {
 | 
| deba@702 |    129 | 	    new_capacity <<= 1;
 | 
| deba@702 |    130 | 	  }
 | 
| deba@702 |    131 | 	  Value* new_values = allocator.allocate(new_capacity);;
 | 
| deba@702 |    132 | 	  for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@702 |    133 | 	    int jd = getGraph()->id(it);
 | 
| deba@702 |    134 | 	    if (id != jd) {
 | 
| deba@702 |    135 | 	      allocator.construct(&(new_values[jd]), values[jd]);
 | 
| deba@702 |    136 | 	      allocator.destroy(&(values[jd]));
 | 
| deba@702 |    137 | 	    }
 | 
| deba@702 |    138 | 	  }
 | 
| deba@702 |    139 | 	  if (capacity != 0) allocator.deallocate(values, capacity);
 | 
| deba@702 |    140 | 	  values = new_values;
 | 
| deba@702 |    141 | 	  capacity = new_capacity;
 | 
| deba@702 |    142 | 	}
 | 
| deba@702 |    143 | 	allocator.construct(&(values[id]), Value());
 | 
| deba@702 |    144 |       }
 | 
| deba@702 |    145 | 		
 | 
| deba@702 |    146 |       void erase(const Key& key) {
 | 
| deba@702 |    147 | 	int id = getGraph()->id(key);
 | 
| deba@702 |    148 | 	allocator.destroy(&(values[id]));
 | 
| deba@702 |    149 |       }
 | 
| deba@702 |    150 | 	
 | 
| deba@702 |    151 |       class iterator {
 | 
| deba@702 |    152 | 	friend class Map;
 | 
| deba@702 |    153 | 	friend class const_iterator;
 | 
| deba@703 |    154 |       private:
 | 
| deba@702 |    155 | 
 | 
| deba@702 |    156 | 	/** Private constructor to initalize the the iterators returned
 | 
| deba@702 |    157 | 	 *  by the begin() and end().
 | 
| deba@702 |    158 | 	 */
 | 
| deba@702 |    159 | 	iterator (Map& pmap, const KeyIt& pit) : map(&pmap), it(pit) {}
 | 
| deba@702 |    160 | 
 | 
| deba@703 |    161 |       public:
 | 
| deba@702 |    162 | 
 | 
| deba@702 |    163 | 	/** Default constructor. 
 | 
| deba@702 |    164 | 	 */
 | 
| deba@702 |    165 | 	iterator() {}
 | 
| deba@702 |    166 | 
 | 
| deba@703 |    167 | 	typedef extended_pair<const Key&, const Key&, 
 | 
| deba@703 |    168 | 			      Value&, Value&> Reference;
 | 
| deba@703 |    169 | 
 | 
| deba@702 |    170 | 	/** Dereference operator for map.
 | 
| deba@702 |    171 | 	 */	 
 | 
| deba@703 |    172 | 	Reference operator*() {
 | 
| deba@703 |    173 | 	  return Reference(it, (*map)[it]);
 | 
| deba@702 |    174 | 	}
 | 
| deba@702 |    175 | 
 | 
| deba@703 |    176 | 	class Pointer {
 | 
| deba@703 |    177 | 	  friend class iterator;
 | 
| deba@703 |    178 | 	private:
 | 
| deba@703 |    179 | 	  Reference data;
 | 
| deba@703 |    180 | 	  Pointer(const Key& key, Value& val) : data(key, val) {}
 | 
| deba@703 |    181 | 	public:
 | 
| deba@703 |    182 | 	  Reference* operator->() {return &data;}
 | 
| deba@703 |    183 | 	};
 | 
| deba@703 |    184 | 
 | 
| deba@702 |    185 | 	/** Arrow operator for map.
 | 
| deba@702 |    186 | 	 */	 
 | 
| deba@703 |    187 | 	Pointer operator->() {
 | 
| deba@703 |    188 | 	  return Pointer(it, ((*map)[it])); 
 | 
| deba@702 |    189 | 	}
 | 
| deba@702 |    190 | 
 | 
| deba@702 |    191 | 	/** The pre increment operator of the map.
 | 
| deba@702 |    192 | 	 */
 | 
| deba@702 |    193 | 	iterator& operator++() { 
 | 
| deba@702 |    194 | 	  map->getGraph()->next(it); 
 | 
| deba@702 |    195 | 	  return *this; 
 | 
| deba@702 |    196 | 	}
 | 
| deba@702 |    197 | 
 | 
| deba@702 |    198 | 	/** The post increment operator of the map.
 | 
| deba@702 |    199 | 	 */
 | 
| deba@702 |    200 | 	iterator operator++(int) { 
 | 
| deba@702 |    201 | 	  iterator tmp(it); 
 | 
| deba@702 |    202 | 	  map.getGraph()->next(it); 
 | 
| deba@702 |    203 | 	  return tmp; 
 | 
| deba@702 |    204 | 	}
 | 
| deba@702 |    205 | 
 | 
| deba@702 |    206 | 	/** The equality operator of the map.
 | 
| deba@702 |    207 | 	 */
 | 
| deba@702 |    208 | 	bool operator==(const_iterator p_it) {
 | 
| deba@702 |    209 | 	  return p_it.it == it;
 | 
| deba@674 |    210 | 	}
 | 
| deba@627 |    211 | 	
 | 
| deba@702 |    212 | 	/** The not-equality operator of the map.
 | 
| deba@702 |    213 | 	 */
 | 
| deba@702 |    214 | 	bool operator!=(const_iterator p_it) {
 | 
| deba@702 |    215 | 	  return !(*this == p_it);
 | 
| deba@674 |    216 | 	}
 | 
| deba@703 |    217 | 
 | 
| deba@627 |    218 | 	
 | 
| deba@703 |    219 |       private:
 | 
| deba@702 |    220 | 	Map* map;
 | 
| deba@702 |    221 | 	KeyIt it;
 | 
| deba@702 |    222 |       };
 | 
| deba@702 |    223 | 
 | 
| deba@702 |    224 |       /** Returns the begin iterator of the map.
 | 
| deba@702 |    225 |        */
 | 
| deba@702 |    226 |       iterator begin() {
 | 
| deba@702 |    227 | 	return iterator(*this, KeyIt(*getGraph()));
 | 
| deba@702 |    228 |       }
 | 
| deba@702 |    229 | 
 | 
| deba@702 |    230 |       /** Returns the end iterator of the map.
 | 
| deba@702 |    231 |        */
 | 
| deba@702 |    232 |       iterator end() {
 | 
| deba@702 |    233 | 	return iterator(*this, INVALID);
 | 
| deba@702 |    234 |       }
 | 
| deba@702 |    235 | 
 | 
| deba@702 |    236 |       class const_iterator {
 | 
| deba@702 |    237 | 	friend class Map;
 | 
| deba@702 |    238 | 	friend class iterator;
 | 
| deba@703 |    239 |       private:
 | 
| deba@702 |    240 | 
 | 
| deba@702 |    241 | 	/** Private constructor to initalize the the iterators returned
 | 
| deba@702 |    242 | 	 *  by the begin() and end().
 | 
| deba@702 |    243 | 	 */
 | 
| deba@703 |    244 | 	const_iterator (const Map& pmap, const KeyIt& pit) 
 | 
| deba@703 |    245 | 	  : map(&pmap), it(pit) {}
 | 
| deba@702 |    246 | 
 | 
| deba@703 |    247 |       public:
 | 
| deba@702 |    248 | 
 | 
| deba@702 |    249 | 	/** Default constructor. 
 | 
| deba@702 |    250 | 	 */
 | 
| deba@702 |    251 | 	const_iterator() {}
 | 
| deba@702 |    252 | 
 | 
| deba@702 |    253 | 	/** Constructor to convert iterator to const_iterator.
 | 
| deba@702 |    254 | 	 */
 | 
| deba@703 |    255 | 	const_iterator(iterator p_it) : map(p_it.map), it(p_it.it) {}
 | 
| deba@702 |    256 |       
 | 
| deba@703 |    257 | 	typedef extended_pair<const Key&, const Key&, 
 | 
| deba@703 |    258 | 	  const Value&, const Value&> Reference;
 | 
| deba@703 |    259 | 
 | 
| deba@702 |    260 | 	/** Dereference operator for map.
 | 
| deba@702 |    261 | 	 */	 
 | 
| deba@703 |    262 | 	Reference operator*() {
 | 
| deba@703 |    263 | 	  return Reference(it, (*map)[it]);
 | 
| deba@702 |    264 | 	}
 | 
| deba@702 |    265 | 
 | 
| deba@703 |    266 | 
 | 
| deba@703 |    267 | 	class Pointer {
 | 
| deba@703 |    268 | 	  friend class const_iterator;
 | 
| deba@703 |    269 | 	private:
 | 
| deba@703 |    270 | 	  Reference data;
 | 
| deba@703 |    271 | 	  Pointer(const Key& key, const Value& val) : data(key, val) {}
 | 
| deba@703 |    272 | 	public:
 | 
| deba@703 |    273 | 	  Reference* operator->() {return &data;}
 | 
| deba@703 |    274 | 	};
 | 
| deba@703 |    275 | 
 | 
| deba@702 |    276 | 	/** Arrow operator for map.
 | 
| deba@702 |    277 | 	 */	 
 | 
| deba@703 |    278 | 	Pointer operator->() {
 | 
| deba@703 |    279 | 	  return Pointer(it, ((*map)[it])); 
 | 
| deba@702 |    280 | 	}
 | 
| deba@702 |    281 | 
 | 
| deba@702 |    282 | 	/** The pre increment operator of the map.
 | 
| deba@702 |    283 | 	 */
 | 
| deba@702 |    284 | 	const_iterator& operator++() { 
 | 
| deba@702 |    285 | 	  map->getGraph()->next(it); 
 | 
| deba@702 |    286 | 	  return *this; 
 | 
| deba@702 |    287 | 	}
 | 
| deba@702 |    288 | 
 | 
| deba@702 |    289 | 	/** The post increment operator of the map.
 | 
| deba@702 |    290 | 	 */
 | 
| deba@702 |    291 | 	const_iterator operator++(int) { 
 | 
| deba@702 |    292 | 	  const_iterator tmp(it); 
 | 
| deba@702 |    293 | 	  map->getGraph()->next(it); 
 | 
| deba@702 |    294 | 	  return tmp; 
 | 
| deba@702 |    295 | 	}
 | 
| deba@702 |    296 | 
 | 
| deba@702 |    297 | 	/** The equality operator of the map.
 | 
| deba@702 |    298 | 	 */
 | 
| deba@702 |    299 | 	bool operator==(const_iterator p_it) {
 | 
| deba@702 |    300 | 	  return p_it.it == it;
 | 
| deba@702 |    301 | 	}
 | 
| deba@702 |    302 | 	
 | 
| deba@702 |    303 | 	/** The not-equality operator of the map.
 | 
| deba@702 |    304 | 	 */
 | 
| deba@702 |    305 | 	bool operator!=(const_iterator p_it) {
 | 
| deba@702 |    306 | 	  return !(*this == p_it);
 | 
| deba@702 |    307 | 	}
 | 
| deba@702 |    308 | 	
 | 
| deba@703 |    309 | 
 | 
| deba@703 |    310 |       private:
 | 
| deba@702 |    311 | 	const Map* map;
 | 
| deba@702 |    312 | 	KeyIt it;
 | 
| deba@702 |    313 |       };
 | 
| deba@702 |    314 | 
 | 
| deba@702 |    315 |       /** Returns the begin const_iterator of the map.
 | 
| deba@702 |    316 |        */
 | 
| deba@702 |    317 |       const_iterator begin() const {
 | 
| deba@702 |    318 | 	return const_iterator(*this, KeyIt(*getGraph()));
 | 
| deba@702 |    319 |       }
 | 
| deba@702 |    320 | 
 | 
| deba@702 |    321 |       /** Returns the end const_iterator of the map.
 | 
| deba@702 |    322 |        */
 | 
| deba@702 |    323 |       const_iterator end() const {
 | 
| deba@702 |    324 | 	return const_iterator(*this, INVALID);
 | 
| deba@702 |    325 |       }
 | 
| deba@702 |    326 | 
 | 
| deba@703 |    327 |     private:
 | 
| deba@703 |    328 |       
 | 
| deba@703 |    329 |       void allocate_memory() {
 | 
| deba@703 |    330 | 	int max_id = -1;
 | 
| deba@703 |    331 | 	for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) {
 | 
| deba@703 |    332 | 	  int id = getGraph()->id(it);
 | 
| deba@703 |    333 | 	  if (id > max_id) {
 | 
| deba@703 |    334 | 	    max_id = id;
 | 
| deba@703 |    335 | 	  }			
 | 
| deba@703 |    336 | 	}
 | 
| deba@703 |    337 | 	if (max_id == -1) {
 | 
| deba@703 |    338 | 	  capacity = 0;
 | 
| deba@703 |    339 | 	  values = 0;
 | 
| deba@703 |    340 | 	  return;
 | 
| deba@703 |    341 | 	}
 | 
| deba@703 |    342 | 	capacity = 1;
 | 
| deba@703 |    343 | 	while (capacity <= max_id) {
 | 
| deba@703 |    344 | 	  capacity <<= 1;
 | 
| deba@703 |    345 | 	}
 | 
| deba@703 |    346 | 	values = allocator.allocate(capacity);	
 | 
| deba@703 |    347 |       }      
 | 
| deba@702 |    348 |       int capacity;
 | 
| deba@702 |    349 |       Value* values;
 | 
| deba@702 |    350 |       Allocator allocator;
 | 
| deba@702 |    351 |     };		
 | 
| deba@674 |    352 |   };
 | 
| deba@627 |    353 | }
 | 
| deba@627 |    354 | 
 | 
| deba@627 |    355 | #endif
 |