src/hugo/array_map_factory.h
author hegyi
Wed, 08 Sep 2004 11:58:06 +0000
changeset 821 283a7fe3a00e
parent 799 3393abe30678
permissions -rw-r--r--
This is needed by path.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
alpar@785
     9
///\ingroup graphmapfactory
alpar@785
    10
///\file
alpar@785
    11
///\brief Graph maps that construates and destruates
alpar@785
    12
///their elements dynamically.
alpar@785
    13
deba@782
    14
namespace hugo {
deba@799
    15
deba@799
    16
alpar@785
    17
/// \addtogroup graphmapfactory
alpar@785
    18
/// @{
deba@799
    19
	
deba@799
    20
  /** The ArrayMapFactory template class is a factory class
deba@799
    21
   *  to create maps for the edge and nodes. This map factory
deba@799
    22
   *  uses the allocators to implement the container function.
deba@799
    23
   *
deba@799
    24
   *  The template parameter is the MapRegistry that the maps
deba@799
    25
   *  will belong to.
deba@799
    26
   */
alpar@785
    27
deba@799
    28
  template <typename MapRegistry> 
deba@799
    29
  class ArrayMapFactory {
deba@782
    30
		
deba@782
    31
  public:
deba@782
    32
		
deba@799
    33
    /// The graph type of the maps. 
deba@782
    34
    typedef typename MapRegistry::Graph Graph;
deba@799
    35
    /// The key type of the maps.
alpar@786
    36
    typedef typename MapRegistry::KeyType KeyType;
deba@799
    37
    /// The iterator to iterate on the keys.
deba@782
    38
    typedef typename MapRegistry::KeyIt KeyIt;
deba@782
    39
deba@799
    40
    /// The MapBase of the Map which imlements the core regisitry function.
deba@782
    41
    typedef typename MapRegistry::MapBase MapBase;
deba@782
    42
		
deba@799
    43
    /** The template Map type.
deba@799
    44
     */
deba@782
    45
    template <typename V, typename A = std::allocator<V> > 
deba@782
    46
    class Map : public MapBase {
deba@782
    47
    
deba@782
    48
      public:
deba@782
    49
deba@799
    50
      /// The value type of the map.
deba@799
    51
      typedef V ValueType;
deba@799
    52
deba@799
    53
      /// The value type of the map.
deba@782
    54
      typedef V Value;
deba@799
    55
      /// The reference type of the map;
deba@799
    56
      typedef Value& Reference;
deba@799
    57
      /// The pointer type of the map;
deba@799
    58
      typedef Value* Pointer;
deba@799
    59
deba@799
    60
      /// The const value type of the map.
deba@799
    61
      typedef const Value ConstValue;
deba@799
    62
      /// The const reference type of the map;
deba@799
    63
      typedef const Value& ConstReference;
deba@799
    64
      /// The pointer type of the map;
deba@799
    65
      typedef const Value* ConstPointer;
deba@799
    66
deba@799
    67
deba@782
    68
      typedef A Allocator;
deba@782
    69
deba@782
    70
	
deba@799
    71
      /** Default constructor for the map.
deba@799
    72
       */
deba@782
    73
      Map() : values(0), capacity(0) {}
deba@782
    74
			
deba@799
    75
      /** Graph and Registry initialized map constructor.
deba@799
    76
       */
deba@782
    77
      Map(const Graph& g, MapRegistry& r) : MapBase(g, r) {
deba@782
    78
	allocate_memory();
deba@782
    79
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
    80
	  int id = MapBase::getGraph()->id(it);
deba@782
    81
	  allocator.construct(&(values[id]), Value());
deba@782
    82
	}								
deba@782
    83
      }
deba@782
    84
deba@799
    85
      /** Constructor to use default value to initialize the map. 
deba@799
    86
       */
deba@782
    87
      Map(const Graph& g, MapRegistry& r, const Value& v) : MapBase(g, r) {
deba@782
    88
	allocate_memory();
deba@782
    89
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
    90
	  int id = MapBase::getGraph()->id(it);
deba@782
    91
	  allocator.construct(&(values[id]), v);
deba@782
    92
	}								
deba@782
    93
      }
deba@782
    94
deba@799
    95
      /** Constructor to copy a map of the same map type.
deba@799
    96
       */
deba@782
    97
      Map(const Map& copy) : MapBase(*copy.graph, *copy.registry) {
deba@782
    98
	capacity = copy.capacity;
deba@782
    99
	if (capacity == 0) return;
deba@782
   100
	values = allocator.allocate(capacity);
deba@782
   101
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   102
	  int id = MapBase::getGraph()->id(it);
deba@782
   103
	  allocator.construct(&(values[id]), copy.values[id]);
deba@782
   104
	}
deba@782
   105
      }
deba@782
   106
deba@799
   107
      /** Constructor to copy a map of an other map type.
deba@799
   108
       */
deba@782
   109
      template <typename CMap> Map(const CMap& copy) 
deba@783
   110
	: MapBase(copy), capacity(0), values(0) {
deba@782
   111
	if (MapBase::getGraph()) {
deba@782
   112
	  allocate_memory();
deba@782
   113
	  for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   114
	    set(it, copy[it]);
deba@782
   115
	  }
deba@782
   116
	}
deba@782
   117
      }
deba@782
   118
deba@799
   119
      /** Assign operator to copy a map of the same map type.
deba@799
   120
       */
deba@782
   121
      Map& operator=(const Map& copy) {
deba@782
   122
	if (&copy == this) return *this;
deba@782
   123
	if (capacity != 0) {
deba@782
   124
	  MapBase::destroy();
deba@782
   125
	  allocator.deallocate(values, capacity);
deba@782
   126
	}
deba@782
   127
	capacity = copy.capacity;
deba@782
   128
	if (capacity == 0) return *this;
deba@782
   129
	values = allocator.allocate(capacity);
deba@782
   130
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   131
	  int id = MapBase::getGraph()->id(it);
deba@782
   132
	  allocator.construct(&(values[id]), copy.values[id]);
deba@782
   133
	}
deba@782
   134
	return *this;
deba@782
   135
      }
deba@782
   136
deba@799
   137
      /** Assign operator to copy a map an other map type.
deba@799
   138
       */
deba@782
   139
      template <typename CMap> Map& operator=(const CMap& copy) {
deba@782
   140
	if (MapBase::getGraph()) {
deba@782
   141
	  MapBase::destroy();
deba@782
   142
	} 
deba@782
   143
	MapBase::operator=(copy);
deba@782
   144
	if (MapBase::getGraph()) {
deba@782
   145
	  allocate_memory();
deba@782
   146
	  for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   147
	    set(it, copy[it]);
deba@782
   148
	  }
deba@782
   149
	}
deba@782
   150
	return *this;
deba@782
   151
      }
deba@782
   152
				
deba@799
   153
      /** The destructor of the map.
deba@799
   154
       */
deba@782
   155
      virtual ~Map() {
deba@782
   156
	if (capacity != 0) {
deba@782
   157
	  MapBase::destroy();
deba@782
   158
	  allocator.deallocate(values, capacity);
deba@782
   159
	}
deba@782
   160
      }
deba@782
   161
	
deba@782
   162
	
deba@799
   163
      /**
deba@799
   164
       * The subscript operator. The map can be subscripted by the
deba@799
   165
       * actual keys of the graph. 
deba@799
   166
       */
alpar@786
   167
      Value& operator[](const KeyType& key) {
deba@782
   168
	int id = MapBase::getGraph()->id(key);
deba@782
   169
	return values[id];
deba@782
   170
      } 
deba@782
   171
		
deba@799
   172
      /**
deba@799
   173
       * The const subscript operator. The map can be subscripted by the
deba@799
   174
       * actual keys of the graph. 
deba@799
   175
       */
alpar@786
   176
      const Value& operator[](const KeyType& key) const {
deba@782
   177
	int id = MapBase::getGraph()->id(key);
deba@782
   178
	return values[id];
deba@782
   179
      }
deba@782
   180
	
deba@799
   181
      /** Setter function of the map. Equivalent with map[key] = val.
deba@799
   182
       *  This is a compatibility feature with the not dereferable maps.
deba@799
   183
       */
alpar@786
   184
      void set(const KeyType& key, const Value& val) {
deba@782
   185
	int id = MapBase::getGraph()->id(key);
deba@782
   186
	values[id] = val;
deba@782
   187
      }
deba@782
   188
		
deba@799
   189
      /** Add a new key to the map. It called by the map registry.
deba@799
   190
       */
alpar@786
   191
      void add(const KeyType& key) {
deba@782
   192
	int id = MapBase::getGraph()->id(key);
deba@782
   193
	if (id >= capacity) {
deba@782
   194
	  int new_capacity = (capacity == 0 ? 1 : capacity);
deba@782
   195
	  while (new_capacity <= id) {
deba@782
   196
	    new_capacity <<= 1;
deba@782
   197
	  }
deba@782
   198
	  Value* new_values = allocator.allocate(new_capacity);;
deba@782
   199
	  for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   200
	    int jd = MapBase::getGraph()->id(it);
deba@782
   201
	    if (id != jd) {
deba@782
   202
	      allocator.construct(&(new_values[jd]), values[jd]);
deba@782
   203
	      allocator.destroy(&(values[jd]));
deba@782
   204
	    }
deba@782
   205
	  }
deba@782
   206
	  if (capacity != 0) allocator.deallocate(values, capacity);
deba@782
   207
	  values = new_values;
deba@782
   208
	  capacity = new_capacity;
deba@782
   209
	}
deba@782
   210
	allocator.construct(&(values[id]), Value());
deba@782
   211
      }
deba@782
   212
		
deba@799
   213
      /** Erase a key from the map. It called by the map registry.
deba@799
   214
       */
alpar@786
   215
      void erase(const KeyType& key) {
deba@782
   216
	int id = MapBase::getGraph()->id(key);
deba@782
   217
	allocator.destroy(&(values[id]));
deba@782
   218
      }
deba@782
   219
deba@799
   220
      /** Clear the data structure.
deba@799
   221
       */
deba@782
   222
      void clear() {	
deba@782
   223
	if (capacity != 0) {
deba@782
   224
	  MapBase::destroy();
deba@782
   225
	  allocator.deallocate(values, capacity);
deba@782
   226
	  capacity = 0;
deba@782
   227
	}
deba@782
   228
      }
deba@817
   229
deba@817
   230
      class iterator;
deba@817
   231
      class const_iterator;
deba@782
   232
	
deba@799
   233
      /** Compatible iterator with the stl maps' iterators.
deba@799
   234
       *  It iterates on pairs of a key and a value.
deba@799
   235
       */
deba@782
   236
      class iterator {
deba@782
   237
	friend class Map;
deba@782
   238
	friend class const_iterator;
deba@782
   239
      private:
deba@782
   240
deba@782
   241
	/** Private constructor to initalize the the iterators returned
deba@782
   242
	 *  by the begin() and end().
deba@782
   243
	 */
deba@782
   244
	iterator (Map& pmap, const KeyIt& pit) : map(&pmap), it(pit) {}
deba@782
   245
deba@782
   246
      public:
deba@782
   247
deba@782
   248
	/** Default constructor. 
deba@782
   249
	 */
deba@782
   250
	iterator() {}
deba@782
   251
alpar@786
   252
	typedef extended_pair<const KeyType&, const KeyType&, 
deba@782
   253
			      Value&, Value&> Reference;
deba@782
   254
deba@782
   255
	/** Dereference operator for map.
deba@782
   256
	 */	 
deba@782
   257
	Reference operator*() {
deba@782
   258
	  return Reference(it, (*map)[it]);
deba@782
   259
	}
deba@782
   260
deba@782
   261
	class Pointer {
deba@782
   262
	  friend class iterator;
deba@782
   263
	private:
deba@782
   264
	  Reference data;
alpar@786
   265
	  Pointer(const KeyType& key, Value& val) : data(key, val) {}
deba@782
   266
	public:
deba@782
   267
	  Reference* operator->() {return &data;}
deba@782
   268
	};
deba@782
   269
deba@782
   270
	/** Arrow operator for map.
deba@782
   271
	 */	 
deba@782
   272
	Pointer operator->() {
deba@782
   273
	  return Pointer(it, ((*map)[it])); 
deba@782
   274
	}
deba@782
   275
deba@782
   276
	/** The pre increment operator of the map.
deba@782
   277
	 */
deba@782
   278
	iterator& operator++() { 
deba@782
   279
	  ++it; 
deba@782
   280
	  return *this; 
deba@782
   281
	}
deba@782
   282
deba@782
   283
	/** The post increment operator of the map.
deba@782
   284
	 */
deba@782
   285
	iterator operator++(int) { 
deba@782
   286
	  iterator tmp(it); 
deba@782
   287
	  ++it; 
deba@782
   288
	  return tmp; 
deba@782
   289
	}
deba@782
   290
deba@782
   291
	/** The equality operator of the map.
deba@782
   292
	 */
deba@782
   293
	bool operator==(const_iterator p_it) {
deba@782
   294
	  return p_it.it == it;
deba@782
   295
	}
deba@782
   296
	
deba@782
   297
	/** The not-equality operator of the map.
deba@782
   298
	 */
deba@782
   299
	bool operator!=(const_iterator p_it) {
deba@782
   300
	  return !(*this == p_it);
deba@782
   301
	}
deba@782
   302
deba@782
   303
	
deba@782
   304
      private:
deba@782
   305
	Map* map;
deba@782
   306
	KeyIt it;
deba@782
   307
      };
deba@782
   308
deba@782
   309
      /** Returns the begin iterator of the map.
deba@782
   310
       */
deba@782
   311
      iterator begin() {
deba@782
   312
	return iterator(*this, KeyIt(*MapBase::getGraph()));
deba@782
   313
      }
deba@782
   314
deba@782
   315
      /** Returns the end iterator of the map.
deba@782
   316
       */
deba@782
   317
      iterator end() {
deba@782
   318
	return iterator(*this, INVALID);
deba@782
   319
      }
deba@782
   320
deba@782
   321
      class const_iterator {
deba@782
   322
	friend class Map;
deba@782
   323
	friend class iterator;
deba@782
   324
      private:
deba@782
   325
deba@782
   326
	/** Private constructor to initalize the the iterators returned
deba@782
   327
	 *  by the begin() and end().
deba@782
   328
	 */
deba@782
   329
	const_iterator (const Map& pmap, const KeyIt& pit) 
deba@782
   330
	  : map(&pmap), it(pit) {}
deba@782
   331
deba@782
   332
      public:
deba@782
   333
deba@782
   334
	/** Default constructor. 
deba@782
   335
	 */
deba@782
   336
	const_iterator() {}
deba@782
   337
deba@782
   338
	/** Constructor to convert iterator to const_iterator.
deba@782
   339
	 */
deba@782
   340
	const_iterator(iterator p_it) : map(p_it.map), it(p_it.it) {}
deba@782
   341
      
alpar@786
   342
	typedef extended_pair<const KeyType&, const KeyType&, 
deba@782
   343
	  const Value&, const Value&> Reference;
deba@782
   344
deba@782
   345
	/** Dereference operator for map.
deba@782
   346
	 */	 
deba@782
   347
	Reference operator*() {
deba@782
   348
	  return Reference(it, (*map)[it]);
deba@782
   349
	}
deba@782
   350
deba@782
   351
deba@782
   352
	class Pointer {
deba@782
   353
	  friend class const_iterator;
deba@782
   354
	private:
deba@782
   355
	  Reference data;
alpar@786
   356
	  Pointer(const KeyType& key, const Value& val) : data(key, val) {}
deba@782
   357
	public:
deba@782
   358
	  Reference* operator->() {return &data;}
deba@782
   359
	};
deba@782
   360
deba@782
   361
	/** Arrow operator for map.
deba@782
   362
	 */	 
deba@782
   363
	Pointer operator->() {
deba@782
   364
	  return Pointer(it, ((*map)[it])); 
deba@782
   365
	}
deba@782
   366
deba@782
   367
	/** The pre increment operator of the map.
deba@782
   368
	 */
deba@782
   369
	const_iterator& operator++() { 
deba@782
   370
	  ++it; 
deba@782
   371
	  return *this; 
deba@782
   372
	}
deba@782
   373
deba@782
   374
	/** The post increment operator of the map.
deba@782
   375
	 */
deba@782
   376
	const_iterator operator++(int) { 
deba@782
   377
	  const_iterator tmp(it); 
deba@782
   378
	  ++it; 
deba@782
   379
	  return tmp; 
deba@782
   380
	}
deba@782
   381
deba@782
   382
	/** The equality operator of the map.
deba@782
   383
	 */
deba@782
   384
	bool operator==(const_iterator p_it) {
deba@782
   385
	  return p_it.it == it;
deba@782
   386
	}
deba@782
   387
	
deba@782
   388
	/** The not-equality operator of the map.
deba@782
   389
	 */
deba@782
   390
	bool operator!=(const_iterator p_it) {
deba@782
   391
	  return !(*this == p_it);
deba@782
   392
	}
deba@782
   393
	
deba@782
   394
deba@782
   395
      private:
deba@782
   396
	const Map* map;
deba@782
   397
	KeyIt it;
deba@782
   398
      };
deba@782
   399
deba@782
   400
      /** Returns the begin const_iterator of the map.
deba@782
   401
       */
deba@782
   402
      const_iterator begin() const {
deba@782
   403
	return const_iterator(*this, KeyIt(*MapBase::getGraph()));
deba@782
   404
      }
deba@782
   405
deba@782
   406
      /** Returns the end const_iterator of the map.
deba@782
   407
       */
deba@782
   408
      const_iterator end() const {
deba@782
   409
	return const_iterator(*this, INVALID);
deba@782
   410
      }
deba@782
   411
deba@782
   412
    private:
deba@782
   413
      
deba@782
   414
      void allocate_memory() {
deba@782
   415
	int max_id = -1;
deba@782
   416
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@782
   417
	  int id = MapBase::getGraph()->id(it);
deba@782
   418
	  if (id > max_id) {
deba@782
   419
	    max_id = id;
deba@782
   420
	  }			
deba@782
   421
	}
deba@782
   422
	if (max_id == -1) {
deba@782
   423
	  capacity = 0;
deba@782
   424
	  values = 0;
deba@782
   425
	  return;
deba@782
   426
	}
deba@782
   427
	capacity = 1;
deba@782
   428
	while (capacity <= max_id) {
deba@782
   429
	  capacity <<= 1;
deba@782
   430
	}
deba@782
   431
	values = allocator.allocate(capacity);	
deba@782
   432
      }      
deba@782
   433
deba@782
   434
      int capacity;
deba@782
   435
      Value* values;
deba@782
   436
      Allocator allocator;
deba@782
   437
    };		
deba@782
   438
  };
deba@799
   439
alpar@785
   440
/// @}
alpar@785
   441
deba@782
   442
}
deba@782
   443
deba@782
   444
#endif