src/work/deba/array_map_factory.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 702 4207f82a1778
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
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