Some bugfixes.
2 * lemon/bits/array_map.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, 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
21 #include <lemon/bits/map_iterator.h>
22 #include <lemon/concept_check.h>
23 #include <lemon/concept/maps.h>
25 /// \ingroup graphmapfactory
27 /// \brief Graph maps that construct and destruct
28 /// their elements dynamically.
32 /// \ingroup graphmapfactory
34 /// \brief Graph map based on the array storage.
36 /// The ArrayMap template class is graph map structure what
37 /// automatically updates the map when a key is added to or erased from
38 /// the map. This map uses the allocators to implement
39 /// the container functionality.
41 /// The template parameter is the AlterationNotifier that the maps
42 /// will belong to and the Value.
44 template <typename _Graph,
47 class ArrayMap : public AlterationNotifier<_Item>::ObserverBase {
52 /// The graph type of the maps.
54 /// The key type of the maps.
57 typedef AlterationNotifier<_Item> Registry;
59 /// The MapBase of the Map which imlements the core regisitry function.
60 typedef typename Registry::ObserverBase Parent;
62 /// The value type of the map.
67 typedef std::allocator<Value> Allocator;
72 /// Graph and Registry initialized map constructor.
73 ArrayMap(const Graph& _g) : graph(&_g) {
75 attach(_g.getNotifier(Item()));
77 for (graph->first(it); it != INVALID; graph->next(it)) {
78 int id = graph->id(it);;
79 allocator.construct(&(values[id]), Value());
83 /// Constructor to use default value to initialize the map.
85 /// It constrates a map and initialize all of the the map.
87 ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
89 attach(_g.getNotifier(_Item()));
91 for (graph->first(it); it != INVALID; graph->next(it)) {
92 int id = graph->id(it);;
93 allocator.construct(&(values[id]), _v);
97 /// Constructor to copy a map of the same map type.
99 ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) {
100 if (copy.attached()) {
101 attach(*copy.getRegistry());
103 capacity = copy.capacity;
104 if (capacity == 0) return;
105 values = allocator.allocate(capacity);
107 for (graph->first(it); it != INVALID; graph->next(it)) {
108 int id = graph->id(it);;
109 allocator.construct(&(values[id]), copy.values[id]);
113 /// \brief The destructor of the map.
115 /// The destructor of the map.
116 virtual ~ArrayMap() {
125 ArrayMap& operator=(const ArrayMap&);
129 using Parent::attach;
130 using Parent::detach;
131 using Parent::attached;
133 const Graph* getGraph() {
140 ///The subscript operator. The map can be subscripted by the
141 ///actual keys of the graph.
143 Value& operator[](const Key& key) {
144 int id = graph->id(key);
149 ///The const subscript operator. The map can be subscripted by the
150 ///actual keys of the graph.
152 const Value& operator[](const Key& key) const {
153 int id = graph->id(key);
157 /// Setter function of the map. Equivalent with map[key] = val.
158 /// This is a compatibility feature with the not dereferable maps.
160 void set(const Key& key, const Value& val) {
166 /// Add a new key to the map. It called by the map registry.
168 void add(const Key& key) {
169 int id = graph->id(key);
170 if (id >= capacity) {
171 int new_capacity = (capacity == 0 ? 1 : capacity);
172 while (new_capacity <= id) {
175 Value* new_values = allocator.allocate(new_capacity);
177 for (graph->first(it); it != INVALID; graph->next(it)) {
178 int jd = graph->id(it);;
180 allocator.construct(&(new_values[jd]), values[jd]);
181 allocator.destroy(&(values[jd]));
184 if (capacity != 0) allocator.deallocate(values, capacity);
186 capacity = new_capacity;
188 allocator.construct(&(values[id]), Value());
191 void add(const std::vector<Key>& keys) {
193 for (int i = 0; i < (int)keys.size(); ++i) {
194 int id = graph->id(keys[i]);
199 if (max_id >= capacity) {
200 int new_capacity = (capacity == 0 ? 1 : capacity);
201 while (new_capacity <= max_id) {
204 Value* new_values = allocator.allocate(new_capacity);
206 for (graph->first(it); it != INVALID; graph->next(it)) {
207 int id = graph->id(it);
209 for (int i = 0; i < (int)keys.size(); ++i) {
210 int jd = graph->id(keys[i]);
217 allocator.construct(&(new_values[id]), values[id]);
218 allocator.destroy(&(values[id]));
220 if (capacity != 0) allocator.deallocate(values, capacity);
222 capacity = new_capacity;
224 for (int i = 0; i < (int)keys.size(); ++i) {
225 int id = graph->id(keys[i]);
226 allocator.construct(&(values[id]), Value());
230 /// Erase a key from the map. It called by the map registry.
232 void erase(const Key& key) {
233 int id = graph->id(key);
234 allocator.destroy(&(values[id]));
237 void erase(const std::vector<Key>& keys) {
238 for (int i = 0; i < (int)keys.size(); ++i) {
239 int id = graph->id(keys[i]);
240 allocator.destroy(&(values[id]));
247 for (graph->first(it); it != INVALID; graph->next(it)) {
248 int id = graph->id(it);;
249 allocator.construct(&(values[id]), Value());
256 for (graph->first(it); it != INVALID; graph->next(it)) {
257 int id = graph->id(it);
258 allocator.destroy(&(values[id]));
260 allocator.deallocate(values, capacity);
267 void allocate_memory() {
268 int max_id = graph->maxId(_Item());
275 while (capacity <= max_id) {
278 values = allocator.allocate(capacity);
290 #endif //LEMON_ARRAY_MAP_H