src/hugo/array_map_factory.h
author deba
Thu, 02 Sep 2004 10:07:30 +0000
changeset 782 df2e45e09652
child 783 81bf2d766164
permissions -rw-r--r--
--This line, and those below, will be ignored--

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