COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/array_map.h @ 891:74589d20dbc3

Last change on this file since 891:74589d20dbc3 was 891:74589d20dbc3, checked in by Balazs Dezso, 20 years ago

template<typename CMap> Map(const CMap&) like constructors and
assigns are removed.

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