src/work/deba/array_map_factory.h
author marci
Tue, 21 Sep 2004 11:54:20 +0000
changeset 892 004636791dd7
parent 702 4207f82a1778
child 921 818510fa3d99
permissions -rw-r--r--
graph_wrappers now pass the tests.
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
deba@627
     9
namespace hugo {
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 (&copy == 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