Correction in doc: skeleton/path.h has been moved to the 'skeletons' module.
2 #ifndef ARRAY_MAP_FACTORY_H
3 #define ARRAY_MAP_FACTORY_H
7 #include <hugo/extended_pair.h>
9 ///\ingroup graphmapfactory
11 ///\brief Graph maps that construates and destruates
12 ///their elements dynamically.
17 /// \addtogroup graphmapfactory
20 /** The ArrayMapFactory template class is a factory class
21 * to create maps for the edge and nodes. This map factory
22 * uses the allocators to implement the container function.
24 * The template parameter is the MapRegistry that the maps
28 template <typename MapRegistry>
29 class ArrayMapFactory {
33 /// The graph type of the maps.
34 typedef typename MapRegistry::Graph Graph;
35 /// The key type of the maps.
36 typedef typename MapRegistry::KeyType KeyType;
37 /// The iterator to iterate on the keys.
38 typedef typename MapRegistry::KeyIt KeyIt;
40 /// The MapBase of the Map which imlements the core regisitry function.
41 typedef typename MapRegistry::MapBase MapBase;
43 /** The template Map type.
45 template <typename V, typename A = std::allocator<V> >
46 class Map : public MapBase {
50 /// The value type of the map.
53 /// The value type of the map.
55 /// The reference type of the map;
56 typedef Value& Reference;
57 /// The pointer type of the map;
58 typedef Value* Pointer;
60 /// The const value type of the map.
61 typedef const Value ConstValue;
62 /// The const reference type of the map;
63 typedef const Value& ConstReference;
64 /// The pointer type of the map;
65 typedef const Value* ConstPointer;
71 /** Default constructor for the map.
73 Map() : values(0), capacity(0) {}
75 /** Graph and Registry initialized map constructor.
77 Map(const Graph& g, MapRegistry& r) : MapBase(g, r) {
79 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
80 int id = MapBase::getGraph()->id(it);
81 allocator.construct(&(values[id]), Value());
85 /** Constructor to use default value to initialize the map.
87 Map(const Graph& g, MapRegistry& r, const Value& v) : MapBase(g, r) {
89 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
90 int id = MapBase::getGraph()->id(it);
91 allocator.construct(&(values[id]), v);
95 /** Constructor to copy a map of the same map type.
97 Map(const Map& copy) : MapBase(*copy.graph, *copy.registry) {
98 capacity = copy.capacity;
99 if (capacity == 0) return;
100 values = allocator.allocate(capacity);
101 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
102 int id = MapBase::getGraph()->id(it);
103 allocator.construct(&(values[id]), copy.values[id]);
107 /** Constructor to copy a map of an other map type.
109 template <typename CMap> Map(const CMap& copy)
110 : MapBase(copy), capacity(0), values(0) {
111 if (MapBase::getGraph()) {
113 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
119 /** Assign operator to copy a map of the same map type.
121 Map& operator=(const Map& copy) {
122 if (© == this) return *this;
125 allocator.deallocate(values, capacity);
127 capacity = copy.capacity;
128 if (capacity == 0) return *this;
129 values = allocator.allocate(capacity);
130 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
131 int id = MapBase::getGraph()->id(it);
132 allocator.construct(&(values[id]), copy.values[id]);
137 /** Assign operator to copy a map an other map type.
139 template <typename CMap> Map& operator=(const CMap& copy) {
140 if (MapBase::getGraph()) {
143 MapBase::operator=(copy);
144 if (MapBase::getGraph()) {
146 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
153 /** The destructor of the map.
158 allocator.deallocate(values, capacity);
164 * The subscript operator. The map can be subscripted by the
165 * actual keys of the graph.
167 Value& operator[](const KeyType& key) {
168 int id = MapBase::getGraph()->id(key);
173 * The const subscript operator. The map can be subscripted by the
174 * actual keys of the graph.
176 const Value& operator[](const KeyType& key) const {
177 int id = MapBase::getGraph()->id(key);
181 /** Setter function of the map. Equivalent with map[key] = val.
182 * This is a compatibility feature with the not dereferable maps.
184 void set(const KeyType& key, const Value& val) {
185 int id = MapBase::getGraph()->id(key);
189 /** Add a new key to the map. It called by the map registry.
191 void add(const KeyType& key) {
192 int id = MapBase::getGraph()->id(key);
193 if (id >= capacity) {
194 int new_capacity = (capacity == 0 ? 1 : capacity);
195 while (new_capacity <= id) {
198 Value* new_values = allocator.allocate(new_capacity);;
199 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
200 int jd = MapBase::getGraph()->id(it);
202 allocator.construct(&(new_values[jd]), values[jd]);
203 allocator.destroy(&(values[jd]));
206 if (capacity != 0) allocator.deallocate(values, capacity);
208 capacity = new_capacity;
210 allocator.construct(&(values[id]), Value());
213 /** Erase a key from the map. It called by the map registry.
215 void erase(const KeyType& key) {
216 int id = MapBase::getGraph()->id(key);
217 allocator.destroy(&(values[id]));
220 /** Clear the data structure.
225 allocator.deallocate(values, capacity);
230 /** Compatible iterator with the stl maps' iterators.
231 * It iterates on pairs of a key and a value.
235 friend class const_iterator;
238 /** Private constructor to initalize the the iterators returned
239 * by the begin() and end().
241 iterator (Map& pmap, const KeyIt& pit) : map(&pmap), it(pit) {}
245 /** Default constructor.
249 typedef extended_pair<const KeyType&, const KeyType&,
250 Value&, Value&> Reference;
252 /** Dereference operator for map.
254 Reference operator*() {
255 return Reference(it, (*map)[it]);
259 friend class iterator;
262 Pointer(const KeyType& key, Value& val) : data(key, val) {}
264 Reference* operator->() {return &data;}
267 /** Arrow operator for map.
269 Pointer operator->() {
270 return Pointer(it, ((*map)[it]));
273 /** The pre increment operator of the map.
275 iterator& operator++() {
280 /** The post increment operator of the map.
282 iterator operator++(int) {
288 /** The equality operator of the map.
290 bool operator==(const_iterator p_it) {
291 return p_it.it == it;
294 /** The not-equality operator of the map.
296 bool operator!=(const_iterator p_it) {
297 return !(*this == p_it);
306 /** Returns the begin iterator of the map.
309 return iterator(*this, KeyIt(*MapBase::getGraph()));
312 /** Returns the end iterator of the map.
315 return iterator(*this, INVALID);
318 class const_iterator {
320 friend class iterator;
323 /** Private constructor to initalize the the iterators returned
324 * by the begin() and end().
326 const_iterator (const Map& pmap, const KeyIt& pit)
327 : map(&pmap), it(pit) {}
331 /** Default constructor.
335 /** Constructor to convert iterator to const_iterator.
337 const_iterator(iterator p_it) : map(p_it.map), it(p_it.it) {}
339 typedef extended_pair<const KeyType&, const KeyType&,
340 const Value&, const Value&> Reference;
342 /** Dereference operator for map.
344 Reference operator*() {
345 return Reference(it, (*map)[it]);
350 friend class const_iterator;
353 Pointer(const KeyType& key, const Value& val) : data(key, val) {}
355 Reference* operator->() {return &data;}
358 /** Arrow operator for map.
360 Pointer operator->() {
361 return Pointer(it, ((*map)[it]));
364 /** The pre increment operator of the map.
366 const_iterator& operator++() {
371 /** The post increment operator of the map.
373 const_iterator operator++(int) {
374 const_iterator tmp(it);
379 /** The equality operator of the map.
381 bool operator==(const_iterator p_it) {
382 return p_it.it == it;
385 /** The not-equality operator of the map.
387 bool operator!=(const_iterator p_it) {
388 return !(*this == p_it);
397 /** Returns the begin const_iterator of the map.
399 const_iterator begin() const {
400 return const_iterator(*this, KeyIt(*MapBase::getGraph()));
403 /** Returns the end const_iterator of the map.
405 const_iterator end() const {
406 return const_iterator(*this, INVALID);
411 void allocate_memory() {
413 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
414 int id = MapBase::getGraph()->id(it);
425 while (capacity <= max_id) {
428 values = allocator.allocate(capacity);