src/hugo/array_map.h
author marci
Mon, 20 Sep 2004 09:05:19 +0000
changeset 888 cc3590763f7f
parent 830 89dfa3bece81
child 891 74589d20dbc3
permissions -rw-r--r--
(none)
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@822
    68
    ArrayMap() : values(0), capacity(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@822
    93
    ArrayMap(const ArrayMap& copy) : MapBase(*copy.graph, *copy.registry) {
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@822
   105
    template <typename CMap> ArrayMap(const CMap& copy) 
deba@822
   106
      : MapBase(copy), capacity(0), values(0) {
deba@822
   107
      if (MapBase::getGraph()) {
deba@822
   108
	allocate_memory();
deba@822
   109
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@822
   110
	  set(it, copy[it]);
deba@822
   111
	}
deba@822
   112
      }
deba@822
   113
    }
deba@822
   114
deba@822
   115
    /** Assign operator to copy a map of the same map type.
deba@822
   116
     */
deba@822
   117
    ArrayMap& operator=(const ArrayMap& copy) {
deba@822
   118
      if (&copy == this) return *this;
deba@822
   119
      if (capacity != 0) {
deba@822
   120
	MapBase::destroy();
deba@822
   121
	allocator.deallocate(values, capacity);
deba@822
   122
      }
deba@822
   123
      capacity = copy.capacity;
deba@822
   124
      if (capacity == 0) return *this;
deba@822
   125
      values = allocator.allocate(capacity);
deba@822
   126
      for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
   127
	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
   128
	allocator.construct(&(values[id]), copy.values[id]);
deba@822
   129
      }
deba@822
   130
      return *this;
deba@822
   131
    }
deba@822
   132
deba@822
   133
    /** Assign operator to copy a map an other map type.
deba@822
   134
     */
deba@822
   135
    template <typename CMap> ArrayMap& operator=(const CMap& copy) {
deba@844
   136
      if (capacity != 0) {
deba@822
   137
	MapBase::destroy();
deba@844
   138
	allocator.deallocate(values, capacity);
deba@844
   139
      }
deba@822
   140
      MapBase::operator=(copy);
deba@822
   141
      if (MapBase::getGraph()) {
deba@822
   142
	allocate_memory();
deba@822
   143
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@822
   144
	  set(it, copy[it]);
deba@822
   145
	}
deba@822
   146
      }
deba@822
   147
      return *this;
deba@822
   148
    }
deba@822
   149
				
deba@822
   150
    /** The destructor of the map.
deba@822
   151
     */
deba@822
   152
    virtual ~ArrayMap() {
deba@822
   153
      if (capacity != 0) {
deba@822
   154
	MapBase::destroy();
deba@822
   155
	allocator.deallocate(values, capacity);
deba@822
   156
      }
deba@822
   157
    }
deba@822
   158
	
deba@822
   159
	
deba@822
   160
    /**
deba@822
   161
     * The subscript operator. The map can be subscripted by the
deba@822
   162
     * actual keys of the graph. 
deba@822
   163
     */
deba@822
   164
    ReferenceType operator[](const KeyType& key) {
deba@844
   165
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   166
      return values[id];
deba@822
   167
    } 
deba@822
   168
		
deba@822
   169
    /**
deba@822
   170
     * The const subscript operator. The map can be subscripted by the
deba@822
   171
     * actual keys of the graph. 
deba@822
   172
     */
deba@822
   173
    ConstReferenceType operator[](const KeyType& key) const {
deba@844
   174
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   175
      return values[id];
deba@822
   176
    }
deba@822
   177
	
deba@822
   178
    /** Setter function of the map. Equivalent with map[key] = val.
deba@822
   179
     *  This is a compatibility feature with the not dereferable maps.
deba@822
   180
     */
deba@822
   181
    void set(const KeyType& key, const ValueType& val) {
deba@844
   182
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   183
      values[id] = val;
deba@822
   184
    }
deba@822
   185
		
deba@822
   186
    /** Add a new key to the map. It called by the map registry.
deba@822
   187
     */
deba@822
   188
    void add(const KeyType& key) {
deba@844
   189
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   190
      if (id >= capacity) {
deba@822
   191
	int new_capacity = (capacity == 0 ? 1 : capacity);
deba@822
   192
	while (new_capacity <= id) {
deba@822
   193
	  new_capacity <<= 1;
deba@822
   194
	}
deba@822
   195
	Value* new_values = allocator.allocate(new_capacity);;
deba@822
   196
	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
deba@844
   197
	  int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
deba@822
   198
	  if (id != jd) {
deba@822
   199
	    allocator.construct(&(new_values[jd]), values[jd]);
deba@822
   200
	    allocator.destroy(&(values[jd]));
deba@822
   201
	  }
deba@822
   202
	}
deba@822
   203
	if (capacity != 0) allocator.deallocate(values, capacity);
deba@822
   204
	values = new_values;
deba@822
   205
	capacity = new_capacity;
deba@822
   206
      }
deba@822
   207
      allocator.construct(&(values[id]), Value());
deba@822
   208
    }
deba@822
   209
		
deba@822
   210
    /** Erase a key from the map. It called by the map registry.
deba@822
   211
     */
deba@822
   212
    void erase(const KeyType& key) {
deba@844
   213
      int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
deba@822
   214
      allocator.destroy(&(values[id]));
deba@822
   215
    }
deba@822
   216
deba@822
   217
    /** Clear the data structure.
deba@822
   218
     */
deba@822
   219
    void clear() {	
deba@822
   220
      if (capacity != 0) {
deba@822
   221
	MapBase::destroy();
deba@822
   222
	allocator.deallocate(values, capacity);
deba@822
   223
	capacity = 0;
deba@822
   224
      }
deba@822
   225
    }
deba@822
   226
deba@822
   227
    /// The stl compatible pair iterator of the map.
deba@822
   228
    typedef MapIterator<ArrayMap> Iterator;
deba@822
   229
    /// The stl compatible const pair iterator of the map.
deba@822
   230
    typedef MapConstIterator<ArrayMap> ConstIterator;
deba@822
   231
deba@822
   232
    /** Returns the begin iterator of the map.
deba@822
   233
     */
deba@822
   234
    Iterator begin() {
deba@822
   235
      return Iterator(*this, KeyIt(*MapBase::getGraph()));
deba@822
   236
    }
deba@822
   237
deba@822
   238
    /** Returns the end iterator of the map.
deba@822
   239
     */
deba@822
   240
    Iterator end() {
deba@822
   241
      return Iterator(*this, INVALID);
deba@822
   242
    }
deba@822
   243
deba@822
   244
    /** Returns the begin ConstIterator of the map.
deba@822
   245
     */
deba@822
   246
    ConstIterator begin() const {
deba@822
   247
      return ConstIterator(*this, KeyIt(*MapBase::getGraph()));
deba@822
   248
    }
deba@822
   249
deba@822
   250
    /** Returns the end const_iterator of the map.
deba@822
   251
     */
deba@822
   252
    ConstIterator end() const {
deba@822
   253
      return ConstIterator(*this, INVALID);
deba@822
   254
    }
deba@822
   255
deba@830
   256
    /// The KeySet of the Map.
deba@830
   257
    typedef MapConstKeySet<ArrayMap> ConstKeySet;
deba@830
   258
deba@830
   259
    /// KeySet getter function.
deba@830
   260
    ConstKeySet keySet() const {
deba@830
   261
      return ConstKeySet(*this); 
deba@830
   262
    }
deba@830
   263
deba@830
   264
    /// The ConstValueSet of the Map.
deba@830
   265
    typedef MapConstValueSet<ArrayMap> ConstValueSet;
deba@830
   266
deba@830
   267
    /// ConstValueSet getter function.
deba@830
   268
    ConstValueSet valueSet() const {
deba@830
   269
      return ConstValueSet(*this);
deba@830
   270
    }
deba@830
   271
deba@830
   272
    /// The ValueSet of the Map.
deba@830
   273
    typedef MapValueSet<ArrayMap> ValueSet;
deba@830
   274
deba@830
   275
    /// ValueSet getter function.
deba@830
   276
    ValueSet valueSet() {
deba@830
   277
      return ValueSet(*this);
deba@830
   278
    }
deba@830
   279
deba@822
   280
  private:
deba@822
   281
      
deba@822
   282
    void allocate_memory() {
deba@844
   283
      int max_id = KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph());
deba@822
   284
      if (max_id == -1) {
deba@822
   285
	capacity = 0;
deba@822
   286
	values = 0;
deba@822
   287
	return;
deba@822
   288
      }
deba@822
   289
      capacity = 1;
deba@822
   290
      while (capacity <= max_id) {
deba@822
   291
	capacity <<= 1;
deba@822
   292
      }
deba@822
   293
      values = allocator.allocate(capacity);	
deba@822
   294
    }      
deba@822
   295
deba@822
   296
    int capacity;
deba@822
   297
    Value* values;
deba@822
   298
    Allocator allocator;
deba@844
   299
deba@844
   300
  public:
deba@844
   301
    // STL  compatibility typedefs.
deba@844
   302
    typedef Iterator iterator;
deba@844
   303
    typedef ConstIterator const_iterator;
deba@844
   304
    typedef typename Iterator::PairValueType value_type;
deba@844
   305
    typedef typename Iterator::KeyType key_type;
deba@844
   306
    typedef typename Iterator::ValueType data_type;
deba@844
   307
    typedef typename Iterator::PairReferenceType reference;
deba@844
   308
    typedef typename Iterator::PairPointerType pointer;
deba@844
   309
    typedef typename ConstIterator::PairReferenceType const_reference;
deba@844
   310
    typedef typename ConstIterator::PairPointerType const_pointer;
deba@844
   311
    typedef int difference_type;		
deba@822
   312
  };		
deba@822
   313
deba@822
   314
/// @}
deba@822
   315
deba@822
   316
}
deba@822
   317
deba@822
   318
#endif