Fix a bug noticed by deba.
2 * src/lemon/array_map.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_ARRAY_MAP_H
18 #define LEMON_ARRAY_MAP_H
24 ///\brief Graph maps that construates and destruates
25 ///their elements dynamically.
30 /// \addtogroup graphmaps
33 /** The ArrayMap template class is graph map structure what
34 * automatically updates the map when a key is added to or erased from
35 * the map. This map factory uses the allocators to implement
36 * the container functionality.
38 * The template parameter is the MapRegistry that the maps
39 * will belong to and the Value.
42 template <typename _Graph,
46 class ArrayMap : public AlterationNotifier<_Item>::ObserverBase {
50 /// The graph type of the maps.
52 /// The key type of the maps.
55 typedef AlterationNotifier<_Item> Registry;
58 /// The iterator to iterate on the keys.
59 typedef _ItemIt KeyIt;
61 /// The MapBase of the Map which imlements the core regisitry function.
62 typedef typename Registry::ObserverBase Parent;
67 /// The value type of the map.
69 /// The reference type of the map;
70 typedef Value& Reference;
71 /// The pointer type of the map;
72 typedef Value* Pointer;
74 /// The const value type of the map.
75 typedef const Value ConstValue;
76 /// The const reference type of the map;
77 typedef const Value& ConstReference;
78 /// The pointer type of the map;
79 typedef const Value* ConstPointer;
83 typedef std::allocator<Value> Allocator;
88 /** Graph and Registry initialized map constructor.
90 ArrayMap(const Graph& _g) : graph(&_g) {
91 attach(_g.getNotifier(_Item()));
93 for (KeyIt it(*graph); it != INVALID; ++it) {
94 int id = graph->id(it);;
95 allocator.construct(&(values[id]), Value());
99 /// Constructor to use default value to initialize the map.
101 /// It constrates a map and initialize all of the the map.
103 ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
104 attach(_g.getNotifier(_Item()));
106 for (KeyIt it(*graph); it != INVALID; ++it) {
107 int id = graph->id(it);;
108 allocator.construct(&(values[id]), _v);
112 /** Constructor to copy a map of the same map type.
114 ArrayMap(const ArrayMap& copy) {
115 if (copy.attached()) {
116 attach(*copy.getRegistry());
118 capacity = copy.capacity;
119 if (capacity == 0) return;
120 values = allocator.allocate(capacity);
121 for (KeyIt it(*graph); it != INVALID; ++it) {
122 int id = graph->id(it);;
123 allocator.construct(&(values[id]), copy.values[id]);
127 using Parent::attach;
128 using Parent::detach;
129 using Parent::attached;
131 /** Assign operator to copy a map of the same map type.
133 ArrayMap& operator=(const ArrayMap& copy) {
134 if (© == this) return *this;
136 if (graph != copy.graph) {
141 if (copy.attached()) {
142 attach(*copy.getRegistry());
144 capacity = copy.capacity;
145 if (capacity == 0) return *this;
146 values = allocator.allocate(capacity);
149 for (KeyIt it(*graph); it != INVALID; ++it) {
150 int id = graph->id(it);;
151 allocator.construct(&(values[id]), copy.values[id]);
157 /** The destructor of the map.
159 virtual ~ArrayMap() {
168 * The subscript operator. The map can be subscripted by the
169 * actual keys of the graph.
171 Reference operator[](const Key& key) {
172 int id = graph->id(key);
177 * The const subscript operator. The map can be subscripted by the
178 * actual keys of the graph.
180 ConstReference operator[](const Key& key) const {
181 int id = graph->id(key);
185 /** Setter function of the map. Equivalent with map[key] = val.
186 * This is a compatibility feature with the not dereferable maps.
188 void set(const Key& key, const Value& val) {
192 /** Add a new key to the map. It called by the map registry.
194 void add(const Key& key) {
195 int id = graph->id(key);
196 if (id >= capacity) {
197 int new_capacity = (capacity == 0 ? 1 : capacity);
198 while (new_capacity <= id) {
201 Value* new_values = allocator.allocate(new_capacity);
202 for (KeyIt it(*graph); it != INVALID; ++it) {
203 int jd = graph->id(it);;
205 allocator.construct(&(new_values[jd]), values[jd]);
206 allocator.destroy(&(values[jd]));
209 if (capacity != 0) allocator.deallocate(values, capacity);
211 capacity = new_capacity;
213 allocator.construct(&(values[id]), Value());
216 /** Erase a key from the map. It called by the map registry.
218 void erase(const Key& key) {
219 int id = graph->id(key);
220 allocator.destroy(&(values[id]));
225 for (KeyIt it(*graph); it != INVALID; ++it) {
226 int id = graph->id(it);;
227 allocator.construct(&(values[id]), Value());
233 for (KeyIt it(*graph); it != INVALID; ++it) {
234 int id = graph->id(it);;
235 allocator.destroy(&(values[id]));
237 allocator.deallocate(values, capacity);
242 // /// The stl compatible pair iterator of the map.
243 // typedef MapIterator<ArrayMap> Iterator;
244 // /// The stl compatible const pair iterator of the map.
245 // typedef MapConstIterator<ArrayMap> ConstIterator;
247 // /** Returns the begin iterator of the map.
249 // Iterator begin() {
250 // return Iterator(*this, KeyIt(*MapBase::getGraph()));
253 // /** Returns the end iterator of the map.
256 // return Iterator(*this, INVALID);
259 // /** Returns the begin ConstIterator of the map.
261 // ConstIterator begin() const {
262 // return ConstIterator(*this, KeyIt(*MapBase::getGraph()));
265 // /** Returns the end const_iterator of the map.
267 // ConstIterator end() const {
268 // return ConstIterator(*this, INVALID);
271 // /// The KeySet of the Map.
272 // typedef MapConstKeySet<ArrayMap> ConstKeySet;
274 // /// KeySet getter function.
275 // ConstKeySet keySet() const {
276 // return ConstKeySet(*this);
279 // /// The ConstValueSet of the Map.
280 // typedef MapConstValueSet<ArrayMap> ConstValueSet;
282 // /// ConstValueSet getter function.
283 // ConstValueSet valueSet() const {
284 // return ConstValueSet(*this);
287 // /// The ValueSet of the Map.
288 // typedef MapValueSet<ArrayMap> ValueSet;
290 // /// ValueSet getter function.
291 // ValueSet valueSet() {
292 // return ValueSet(*this);
297 void allocate_memory() {
298 int max_id = graph->maxId(_Item());
305 while (capacity <= max_id) {
308 values = allocator.allocate(capacity);
317 // // STL compatibility typedefs.
318 // typedef Iterator iterator;
319 // typedef ConstIterator const_iterator;
320 // typedef typename Iterator::PairValue value_type;
321 // typedef typename Iterator::Key key_type;
322 // typedef typename Iterator::Value data_type;
323 // typedef typename Iterator::PairReference reference;
324 // typedef typename Iterator::PairPointer pointer;
325 // typedef typename ConstIterator::PairReference const_reference;
326 // typedef typename ConstIterator::PairPointer const_pointer;
327 // typedef int difference_type;
330 template <typename _Base>
331 class ArrayMappableGraphExtender : public _Base {
334 typedef ArrayMappableGraphExtender<_Base> Graph;
335 typedef _Base Parent;
337 typedef typename Parent::Node Node;
338 typedef typename Parent::NodeIt NodeIt;
339 typedef typename Parent::NodeNotifier NodeObserverRegistry;
341 typedef typename Parent::Edge Edge;
342 typedef typename Parent::EdgeIt EdgeIt;
343 typedef typename Parent::EdgeNotifier EdgeObserverRegistry;
347 template <typename _Value>
348 class NodeMap : public ArrayMap<Graph, Node, NodeIt, _Value> {
350 typedef ArrayMappableGraphExtender<_Base> Graph;
352 typedef typename Graph::Node Node;
353 typedef typename Graph::NodeIt NodeIt;
355 typedef ArrayMap<Graph, Node, NodeIt, _Value> Parent;
357 //typedef typename Parent::Graph Graph;
358 typedef typename Parent::Value Value;
360 NodeMap(const Graph& g)
362 NodeMap(const Graph& g, const Value& v)
367 template <typename _Value>
368 class EdgeMap : public ArrayMap<Graph, Edge, EdgeIt, _Value> {
370 typedef ArrayMappableGraphExtender<_Base> Graph;
372 typedef typename Graph::Edge Edge;
373 typedef typename Graph::EdgeIt EdgeIt;
375 typedef ArrayMap<Graph, Edge, EdgeIt, _Value> Parent;
377 //typedef typename Parent::Graph Graph;
378 typedef typename Parent::Value Value;
380 EdgeMap(const Graph& g)
382 EdgeMap(const Graph& g, const Value& v)
393 #endif //LEMON_ARRAY_MAP_H