7 #include <hugo/map_iterator.h>
8 #include <hugo/map_bits.h>
12 ///\brief Graph maps that construates and destruates
13 ///their elements dynamically.
18 /// \addtogroup graphmaps
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.
26 * The template parameter is the MapRegistry that the maps
27 * will belong to and the ValueType.
30 template <typename MapRegistry, typename Value>
31 class ArrayMap : public MapRegistry::MapBase {
33 template <typename MR, typename V> friend class ArrayMap;
37 /// The graph type of the maps.
38 typedef typename MapRegistry::Graph Graph;
39 /// The key type of the maps.
40 typedef typename MapRegistry::KeyType KeyType;
41 /// The iterator to iterate on the keys.
42 typedef typename MapRegistry::KeyIt KeyIt;
44 /// The MapBase of the Map which imlements the core regisitry function.
45 typedef typename MapRegistry::MapBase MapBase;
50 /// The value type of the map.
51 typedef Value ValueType;
52 /// The reference type of the map;
53 typedef Value& ReferenceType;
54 /// The pointer type of the map;
55 typedef Value* PointerType;
57 /// The const value type of the map.
58 typedef const Value ConstValueType;
59 /// The const reference type of the map;
60 typedef const Value& ConstReferenceType;
61 /// The pointer type of the map;
62 typedef const Value* ConstPointerType;
65 typedef std::allocator<Value> Allocator;
68 /** Graph and Registry initialized map constructor.
70 ArrayMap(const Graph& g, MapRegistry& r) : MapBase(g, r) {
72 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
73 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
74 allocator.construct(&(values[id]), Value());
78 /** Constructor to use default value to initialize the map.
80 ArrayMap(const Graph& g, MapRegistry& r, const Value& v)
83 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
84 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
85 allocator.construct(&(values[id]), v);
89 /** Constructor to copy a map of the same map type.
91 ArrayMap(const ArrayMap& copy) : MapBase(copy) {
92 capacity = copy.capacity;
93 if (capacity == 0) return;
94 values = allocator.allocate(capacity);
95 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
96 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
97 allocator.construct(&(values[id]), copy.values[id]);
101 /** Constructor to copy a map of an other map type.
103 template <typename TT>
104 ArrayMap(const ArrayMap<MapRegistry, TT>& copy)
106 capacity = copy.capacity;
107 if (capacity == 0) return;
108 values = allocator.allocate(capacity);
109 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
110 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
111 allocator.construct(&(values[id]), copy.values[id]);
115 /** Assign operator to copy a map of the same map type.
117 ArrayMap& operator=(const ArrayMap& copy) {
118 if (© == this) return *this;
120 if (MapBase::getGraph() != copy.getGraph()) {
123 allocator.deallocate(values, capacity);
126 MapBase::operator=(copy);
127 capacity = copy.capacity;
128 if (capacity == 0) return *this;
129 values = allocator.allocate(capacity);
132 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
133 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
134 allocator.construct(&(values[id]), copy.values[id]);
140 /** Assign operator to copy a map of an other map type.
142 template <typename TT>
143 ArrayMap& operator=(const ArrayMap<MapRegistry, TT>& copy) {
145 if (MapBase::getGraph() != copy.getGraph()) {
148 allocator.deallocate(values, capacity);
151 MapBase::operator=(copy);
153 capacity = copy.capacity;
154 if (capacity == 0) return *this;
155 values = allocator.allocate(capacity);
158 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
159 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
160 allocator.construct(&(values[id]), copy.values[id]);
166 /** The destructor of the map.
168 virtual ~ArrayMap() {
171 allocator.deallocate(values, capacity);
177 * The subscript operator. The map can be subscripted by the
178 * actual keys of the graph.
180 ReferenceType operator[](const KeyType& key) {
181 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
186 * The const subscript operator. The map can be subscripted by the
187 * actual keys of the graph.
189 ConstReferenceType operator[](const KeyType& key) const {
190 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
194 /** Setter function of the map. Equivalent with map[key] = val.
195 * This is a compatibility feature with the not dereferable maps.
197 void set(const KeyType& key, const ValueType& val) {
198 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
202 /** Add a new key to the map. It called by the map registry.
204 void add(const KeyType& key) {
205 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
206 if (id >= capacity) {
207 int new_capacity = (capacity == 0 ? 1 : capacity);
208 while (new_capacity <= id) {
211 Value* new_values = allocator.allocate(new_capacity);;
212 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
213 int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
215 allocator.construct(&(new_values[jd]), values[jd]);
216 allocator.destroy(&(values[jd]));
219 if (capacity != 0) allocator.deallocate(values, capacity);
221 capacity = new_capacity;
223 allocator.construct(&(values[id]), Value());
226 /** Erase a key from the map. It called by the map registry.
228 void erase(const KeyType& key) {
229 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
230 allocator.destroy(&(values[id]));
233 /** Clear the data structure.
238 allocator.deallocate(values, capacity);
243 /// The stl compatible pair iterator of the map.
244 typedef MapIterator<ArrayMap> Iterator;
245 /// The stl compatible const pair iterator of the map.
246 typedef MapConstIterator<ArrayMap> ConstIterator;
248 /** Returns the begin iterator of the map.
251 return Iterator(*this, KeyIt(*MapBase::getGraph()));
254 /** Returns the end iterator of the map.
257 return Iterator(*this, INVALID);
260 /** Returns the begin ConstIterator of the map.
262 ConstIterator begin() const {
263 return ConstIterator(*this, KeyIt(*MapBase::getGraph()));
266 /** Returns the end const_iterator of the map.
268 ConstIterator end() const {
269 return ConstIterator(*this, INVALID);
272 /// The KeySet of the Map.
273 typedef MapConstKeySet<ArrayMap> ConstKeySet;
275 /// KeySet getter function.
276 ConstKeySet keySet() const {
277 return ConstKeySet(*this);
280 /// The ConstValueSet of the Map.
281 typedef MapConstValueSet<ArrayMap> ConstValueSet;
283 /// ConstValueSet getter function.
284 ConstValueSet valueSet() const {
285 return ConstValueSet(*this);
288 /// The ValueSet of the Map.
289 typedef MapValueSet<ArrayMap> ValueSet;
291 /// ValueSet getter function.
292 ValueSet valueSet() {
293 return ValueSet(*this);
298 void allocate_memory() {
299 int max_id = KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph());
306 while (capacity <= max_id) {
309 values = allocator.allocate(capacity);
317 // STL compatibility typedefs.
318 typedef Iterator iterator;
319 typedef ConstIterator const_iterator;
320 typedef typename Iterator::PairValueType value_type;
321 typedef typename Iterator::KeyType key_type;
322 typedef typename Iterator::ValueType data_type;
323 typedef typename Iterator::PairReferenceType reference;
324 typedef typename Iterator::PairPointerType pointer;
325 typedef typename ConstIterator::PairReferenceType const_reference;
326 typedef typename ConstIterator::PairPointerType const_pointer;
327 typedef int difference_type;