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