src/hugo/array_map.h
author deba
Mon, 20 Sep 2004 22:57:48 +0000
changeset 891 74589d20dbc3
parent 844 9bf990cb066d
child 897 ef09eee53b09
permissions -rw-r--r--
template<typename CMap> Map(const CMap&) like constructors and
assigns are removed.
deba@822
     1
// -*- c++ -*-
deba@822
     2
#ifndef ARRAY_MAP_H
deba@822
     3
#define ARRAY_MAP_H
deba@822
     4
deba@822
     5
#include <memory>
deba@822
     6
deba@822
     7
#include <hugo/map_iterator.h>
deba@844
     8
#include <hugo/map_bits.h>
deba@822
     9
deba@822
    10
///\ingroup graphmaps
deba@822
    11
///\file
deba@822
    12
///\brief Graph maps that construates and destruates
deba@822
    13
///their elements dynamically.
deba@822
    14
deba@822
    15
namespace hugo {
deba@822
    16
deba@822
    17
deba@822
    18
  /// \addtogroup graphmaps
deba@822
    19
  /// @{
deba@822
    20
	
deba@822
    21
  /** The ArrayMap template class is graph map structure what
deba@822
    22
   *  automatically updates the map when a key is added to or erased from
deba@822
    23
   *  the map. This map factory uses the allocators to implement 
deba@822
    24
   *  the container functionality.
deba@822
    25
   *
deba@822
    26
   *  The template parameter is the MapRegistry that the maps
deba@822
    27
   *  will belong to and the ValueType.
deba@822
    28
   */
deba@822
    29
deba@822
    30
  template <typename MapRegistry, typename Value> 
deba@822
    31
  class ArrayMap : public MapRegistry::MapBase {
deba@822
    32
		
deba@822
    33
  public:
deba@822
    34
		
deba@822
    35
    /// The graph type of the maps. 
deba@822
    36
    typedef typename MapRegistry::Graph Graph;
deba@822
    37
    /// The key type of the maps.
deba@822
    38
    typedef typename MapRegistry::KeyType KeyType;
deba@822
    39
    /// The iterator to iterate on the keys.
deba@822
    40
    typedef typename MapRegistry::KeyIt KeyIt;
deba@822
    41
deba@822
    42
    /// The MapBase of the Map which imlements the core regisitry function.
deba@822
    43
    typedef typename MapRegistry::MapBase MapBase;
deba@822
    44
		
deba@822
    45
    
deba@822
    46
  public:
deba@822
    47
deba@822
    48
    /// The value type of the map.
deba@822
    49
    typedef Value ValueType;
deba@822
    50
    /// The reference type of the map;
deba@822
    51
    typedef Value& ReferenceType;
deba@822
    52
    /// The pointer type of the map;
deba@822
    53
    typedef Value* PointerType;
deba@822
    54
deba@822
    55
    /// The const value type of the map.
deba@822
    56
    typedef const Value ConstValueType;
deba@822
    57
    /// The const reference type of the map;
deba@822
    58
    typedef const Value& ConstReferenceType;
deba@822
    59
    /// The pointer type of the map;
deba@822
    60
    typedef const Value* ConstPointerType;
deba@822
    61
deba@822
    62
deba@822
    63
    typedef std::allocator<Value> Allocator;
deba@822
    64
deba@822
    65
	
deba@822
    66
    /** Default constructor for the map.
deba@822
    67
     */
deba@891
    68
    ArrayMap() : capacity(0), values(0) {}
deba@822
    69
			
deba@822
    70
    /** Graph and Registry initialized map constructor.
deba@822
    71
     */
deba@822
    72
    ArrayMap(const Graph& g, MapRegistry& r) : MapBase(g, r) {
deba@822
    73
      allocate_memory();
deba@822
    74
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
    75
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
    76
	allocator.construct(&(values[id]), Value());
deba@822
    77
      }								
deba@822
    78
    }
deba@822
    79
deba@822
    80
    /** Constructor to use default value to initialize the map. 
deba@822
    81
     */
deba@822
    82
    ArrayMap(const Graph& g, MapRegistry& r, const Value& v) 
deba@822
    83
      : MapBase(g, r) {
deba@822
    84
      allocate_memory();
deba@822
    85
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
    86
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
    87
	allocator.construct(&(values[id]), v);
deba@822
    88
      }								
deba@822
    89
    }
deba@822
    90
deba@822
    91
    /** Constructor to copy a map of the same map type.
deba@822
    92
     */
deba@891
    93
    ArrayMap(const ArrayMap& copy) : MapBase(copy) {
deba@822
    94
      capacity = copy.capacity;
deba@822
    95
      if (capacity == 0) return;
deba@822
    96
      values = allocator.allocate(capacity);
deba@822
    97
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
    98
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
    99
	allocator.construct(&(values[id]), copy.values[id]);
deba@822
   100
      }
deba@822
   101
    }
deba@822
   102
deba@822
   103
    /** Constructor to copy a map of an other map type.
deba@822
   104
     */
deba@891
   105
    template <typename TT>
deba@891
   106
    ArrayMap(const ArrayMap<MapRegistry, TT>& copy) 
deba@891
   107
      : MapBase(copy) {
deba@891
   108
      capacity = copy.capacity;
deba@891
   109
      if (capacity == 0) return;
deba@891
   110
      values = allocator.allocate(capacity);
deba@891
   111
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@891
   112
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@891
   113
	allocator.construct(&(values[id]), copy.values[id]);
deba@822
   114
      }
deba@822
   115
    }
deba@822
   116
deba@822
   117
    /** Assign operator to copy a map of the same map type.
deba@822
   118
     */
deba@822
   119
    ArrayMap& operator=(const ArrayMap& copy) {
deba@822
   120
      if (&copy == this) return *this;
deba@891
   121
deba@822
   122
      if (capacity != 0) {
deba@822
   123
	MapBase::destroy();
deba@822
   124
	allocator.deallocate(values, capacity);
deba@822
   125
      }
deba@891
   126
deba@891
   127
      MapBase::operator=(copy);
deba@891
   128
deba@822
   129
      capacity = copy.capacity;
deba@822
   130
      if (capacity == 0) return *this;
deba@822
   131
      values = allocator.allocate(capacity);
deba@891
   132
deba@822
   133
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
   134
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
   135
	allocator.construct(&(values[id]), copy.values[id]);
deba@822
   136
      }
deba@891
   137
deba@822
   138
      return *this;
deba@822
   139
    }
deba@822
   140
deba@891
   141
    /** Assign operator to copy a map of an other map type.
deba@822
   142
     */
deba@891
   143
    template <typename TT>
deba@891
   144
    ArrayMap& operator=(const ArrayMap<MapRegistry, TT>& copy) {
deba@844
   145
      if (capacity != 0) {
deba@822
   146
	MapBase::destroy();
deba@844
   147
	allocator.deallocate(values, capacity);
deba@844
   148
      }
deba@891
   149
deba@822
   150
      MapBase::operator=(copy);
deba@891
   151
deba@891
   152
      capacity = copy.capacity;
deba@891
   153
      if (capacity == 0) return *this;
deba@891
   154
      values = allocator.allocate(capacity);
deba@891
   155
deba@891
   156
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@891
   157
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@891
   158
	allocator.construct(&(values[id]), copy.values[id]);
deba@822
   159
      }
deba@891
   160
deba@822
   161
      return *this;
deba@822
   162
    }
deba@822
   163
				
deba@822
   164
    /** The destructor of the map.
deba@822
   165
     */
deba@822
   166
    virtual ~ArrayMap() {
deba@822
   167
      if (capacity != 0) {
deba@822
   168
	MapBase::destroy();
deba@822
   169
	allocator.deallocate(values, capacity);
deba@822
   170
      }
deba@822
   171
    }
deba@822
   172
	
deba@822
   173
	
deba@822
   174
    /**
deba@822
   175
     * The subscript operator. The map can be subscripted by the
deba@822
   176
     * actual keys of the graph. 
deba@822
   177
     */
deba@822
   178
    ReferenceType operator[](const KeyType& key) {
deba@844
   179
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   180
      return values[id];
deba@822
   181
    } 
deba@822
   182
		
deba@822
   183
    /**
deba@822
   184
     * The const subscript operator. The map can be subscripted by the
deba@822
   185
     * actual keys of the graph. 
deba@822
   186
     */
deba@822
   187
    ConstReferenceType operator[](const KeyType& key) const {
deba@844
   188
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   189
      return values[id];
deba@822
   190
    }
deba@822
   191
	
deba@822
   192
    /** Setter function of the map. Equivalent with map[key] = val.
deba@822
   193
     *  This is a compatibility feature with the not dereferable maps.
deba@822
   194
     */
deba@822
   195
    void set(const KeyType& key, const ValueType& val) {
deba@844
   196
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   197
      values[id] = val;
deba@822
   198
    }
deba@822
   199
		
deba@822
   200
    /** Add a new key to the map. It called by the map registry.
deba@822
   201
     */
deba@822
   202
    void add(const KeyType& key) {
deba@844
   203
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   204
      if (id >= capacity) {
deba@822
   205
	int new_capacity = (capacity == 0 ? 1 : capacity);
deba@822
   206
	while (new_capacity <= id) {
deba@822
   207
	  new_capacity <<= 1;
deba@822
   208
	}
deba@822
   209
	Value* new_values = allocator.allocate(new_capacity);;
deba@822
   210
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
   211
	  int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
   212
	  if (id != jd) {
deba@822
   213
	    allocator.construct(&(new_values[jd]), values[jd]);
deba@822
   214
	    allocator.destroy(&(values[jd]));
deba@822
   215
	  }
deba@822
   216
	}
deba@822
   217
	if (capacity != 0) allocator.deallocate(values, capacity);
deba@822
   218
	values = new_values;
deba@822
   219
	capacity = new_capacity;
deba@822
   220
      }
deba@822
   221
      allocator.construct(&(values[id]), Value());
deba@822
   222
    }
deba@822
   223
		
deba@822
   224
    /** Erase a key from the map. It called by the map registry.
deba@822
   225
     */
deba@822
   226
    void erase(const KeyType& key) {
deba@844
   227
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   228
      allocator.destroy(&(values[id]));
deba@822
   229
    }
deba@822
   230
deba@822
   231
    /** Clear the data structure.
deba@822
   232
     */
deba@822
   233
    void clear() {	
deba@822
   234
      if (capacity != 0) {
deba@822
   235
	MapBase::destroy();
deba@822
   236
	allocator.deallocate(values, capacity);
deba@822
   237
	capacity = 0;
deba@822
   238
      }
deba@822
   239
    }
deba@822
   240
deba@822
   241
    /// The stl compatible pair iterator of the map.
deba@822
   242
    typedef MapIterator<ArrayMap> Iterator;
deba@822
   243
    /// The stl compatible const pair iterator of the map.
deba@822
   244
    typedef MapConstIterator<ArrayMap> ConstIterator;
deba@822
   245
deba@822
   246
    /** Returns the begin iterator of the map.
deba@822
   247
     */
deba@822
   248
    Iterator begin() {
deba@822
   249
      return Iterator(*this, KeyIt(*MapBase::getGraph()));
deba@822
   250
    }
deba@822
   251
deba@822
   252
    /** Returns the end iterator of the map.
deba@822
   253
     */
deba@822
   254
    Iterator end() {
deba@822
   255
      return Iterator(*this, INVALID);
deba@822
   256
    }
deba@822
   257
deba@822
   258
    /** Returns the begin ConstIterator of the map.
deba@822
   259
     */
deba@822
   260
    ConstIterator begin() const {
deba@822
   261
      return ConstIterator(*this, KeyIt(*MapBase::getGraph()));
deba@822
   262
    }
deba@822
   263
deba@822
   264
    /** Returns the end const_iterator of the map.
deba@822
   265
     */
deba@822
   266
    ConstIterator end() const {
deba@822
   267
      return ConstIterator(*this, INVALID);
deba@822
   268
    }
deba@822
   269
deba@830
   270
    /// The KeySet of the Map.
deba@830
   271
    typedef MapConstKeySet<ArrayMap> ConstKeySet;
deba@830
   272
deba@830
   273
    /// KeySet getter function.
deba@830
   274
    ConstKeySet keySet() const {
deba@830
   275
      return ConstKeySet(*this); 
deba@830
   276
    }
deba@830
   277
deba@830
   278
    /// The ConstValueSet of the Map.
deba@830
   279
    typedef MapConstValueSet<ArrayMap> ConstValueSet;
deba@830
   280
deba@830
   281
    /// ConstValueSet getter function.
deba@830
   282
    ConstValueSet valueSet() const {
deba@830
   283
      return ConstValueSet(*this);
deba@830
   284
    }
deba@830
   285
deba@830
   286
    /// The ValueSet of the Map.
deba@830
   287
    typedef MapValueSet<ArrayMap> ValueSet;
deba@830
   288
deba@830
   289
    /// ValueSet getter function.
deba@830
   290
    ValueSet valueSet() {
deba@830
   291
      return ValueSet(*this);
deba@830
   292
    }
deba@830
   293
deba@822
   294
  private:
deba@822
   295
      
deba@822
   296
    void allocate_memory() {
deba@844
   297
      int max_id = KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph());
deba@822
   298
      if (max_id == -1) {
deba@822
   299
	capacity = 0;
deba@822
   300
	values = 0;
deba@822
   301
	return;
deba@822
   302
      }
deba@822
   303
      capacity = 1;
deba@822
   304
      while (capacity <= max_id) {
deba@822
   305
	capacity <<= 1;
deba@822
   306
      }
deba@822
   307
      values = allocator.allocate(capacity);	
deba@822
   308
    }      
deba@822
   309
deba@822
   310
    int capacity;
deba@822
   311
    Value* values;
deba@822
   312
    Allocator allocator;
deba@844
   313
deba@844
   314
  public:
deba@844
   315
    // STL  compatibility typedefs.
deba@844
   316
    typedef Iterator iterator;
deba@844
   317
    typedef ConstIterator const_iterator;
deba@844
   318
    typedef typename Iterator::PairValueType value_type;
deba@844
   319
    typedef typename Iterator::KeyType key_type;
deba@844
   320
    typedef typename Iterator::ValueType data_type;
deba@844
   321
    typedef typename Iterator::PairReferenceType reference;
deba@844
   322
    typedef typename Iterator::PairPointerType pointer;
deba@844
   323
    typedef typename ConstIterator::PairReferenceType const_reference;
deba@844
   324
    typedef typename ConstIterator::PairPointerType const_pointer;
deba@844
   325
    typedef int difference_type;		
deba@822
   326
  };		
deba@822
   327
deba@822
   328
/// @}
deba@822
   329
deba@822
   330
}
deba@822
   331
deba@822
   332
#endif