3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_BITS_ARRAY_MAP_H
20 #define LEMON_BITS_ARRAY_MAP_H
24 #include <lemon/bits/traits.h>
25 #include <lemon/bits/alteration_notifier.h>
27 /// \ingroup graphbits
29 /// \brief Graph map based on the array storage.
33 /// \ingroup graphbits
35 /// \brief Graph map based on the array storage.
37 /// The ArrayMap template class is graph map structure what
38 /// automatically updates the map when a key is added to or erased from
39 /// the map. This map uses the allocators to implement
40 /// the container functionality.
42 /// The template parameter is the Graph the current Item type and
43 /// the Value type of the map.
44 template <typename _Graph, typename _Item, typename _Value>
46 : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
48 /// The graph type of the maps.
50 /// The item type of the map.
52 /// The reference map tag.
53 typedef True ReferenceMapTag;
55 /// The key type of the maps.
57 /// The value type of the map.
60 /// The const reference type of the map.
61 typedef const _Value& ConstReference;
62 /// The reference type of the map.
63 typedef _Value& Reference;
65 /// The notifier type.
66 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
68 /// The MapBase of the Map which imlements the core regisitry function.
69 typedef typename Notifier::ObserverBase Parent;
72 typedef std::allocator<Value> Allocator;
76 /// \brief Graph initialized map constructor.
78 /// Graph initialized map constructor.
79 ArrayMap(const Graph& graph) {
80 Parent::attach(graph.getNotifier(Item()));
82 Notifier* notifier = Parent::getNotifier();
84 for (notifier->first(it); it != INVALID; notifier->next(it)) {
85 int id = notifier->id(it);;
86 allocator.construct(&(values[id]), Value());
90 /// \brief Constructor to use default value to initialize the map.
92 /// It constructs a map and initialize all of the the map.
93 ArrayMap(const Graph& graph, const Value& value) {
94 Parent::attach(graph.getNotifier(Item()));
96 Notifier* notifier = Parent::getNotifier();
98 for (notifier->first(it); it != INVALID; notifier->next(it)) {
99 int id = notifier->id(it);;
100 allocator.construct(&(values[id]), value);
104 /// \brief Constructor to copy a map of the same map type.
106 /// Constructor to copy a map of the same map type.
107 ArrayMap(const ArrayMap& copy) : Parent() {
108 if (copy.attached()) {
109 attach(*copy.getNotifier());
111 capacity = copy.capacity;
112 if (capacity == 0) return;
113 values = allocator.allocate(capacity);
114 Notifier* notifier = Parent::getNotifier();
116 for (notifier->first(it); it != INVALID; notifier->next(it)) {
117 int id = notifier->id(it);;
118 allocator.construct(&(values[id]), copy.values[id]);
122 /// \brief The destructor of the map.
124 /// The destructor of the map.
125 virtual ~ArrayMap() {
134 ArrayMap& operator=(const ArrayMap&);
138 using Parent::attach;
139 using Parent::detach;
140 using Parent::attached;
144 /// \brief The subscript operator.
146 /// The subscript operator. The map can be subscripted by the
147 /// actual keys of the graph.
148 Value& operator[](const Key& key) {
149 int id = Parent::getNotifier()->id(key);
153 /// \brief The const subscript operator.
155 /// The const subscript operator. The map can be subscripted by the
156 /// actual keys of the graph.
157 const Value& operator[](const Key& key) const {
158 int id = Parent::getNotifier()->id(key);
162 /// \brief Setter function of the map.
164 /// Setter function of the map. Equivalent with map[key] = val.
165 /// This is a compatibility feature with the not dereferable maps.
166 void set(const Key& key, const Value& val) {
172 /// \brief Adds a new key to the map.
174 /// It adds a new key to the map. It called by the observer notifier
175 /// and it overrides the add() member function of the observer base.
176 virtual void add(const Key& key) {
177 Notifier* notifier = Parent::getNotifier();
178 int id = notifier->id(key);
179 if (id >= capacity) {
180 int new_capacity = (capacity == 0 ? 1 : capacity);
181 while (new_capacity <= id) {
184 Value* new_values = allocator.allocate(new_capacity);
186 for (notifier->first(it); it != INVALID; notifier->next(it)) {
187 int jd = notifier->id(it);;
189 allocator.construct(&(new_values[jd]), values[jd]);
190 allocator.destroy(&(values[jd]));
193 if (capacity != 0) allocator.deallocate(values, capacity);
195 capacity = new_capacity;
197 allocator.construct(&(values[id]), Value());
200 /// \brief Adds more new keys to the map.
202 /// It adds more new keys to the map. It called by the observer notifier
203 /// and it overrides the add() member function of the observer base.
204 virtual void add(const std::vector<Key>& keys) {
205 Notifier* notifier = Parent::getNotifier();
207 for (int i = 0; i < (int)keys.size(); ++i) {
208 int id = notifier->id(keys[i]);
213 if (max_id >= capacity) {
214 int new_capacity = (capacity == 0 ? 1 : capacity);
215 while (new_capacity <= max_id) {
218 Value* new_values = allocator.allocate(new_capacity);
220 for (notifier->first(it); it != INVALID; notifier->next(it)) {
221 int id = notifier->id(it);
223 for (int i = 0; i < (int)keys.size(); ++i) {
224 int jd = notifier->id(keys[i]);
231 allocator.construct(&(new_values[id]), values[id]);
232 allocator.destroy(&(values[id]));
234 if (capacity != 0) allocator.deallocate(values, capacity);
236 capacity = new_capacity;
238 for (int i = 0; i < (int)keys.size(); ++i) {
239 int id = notifier->id(keys[i]);
240 allocator.construct(&(values[id]), Value());
244 /// \brief Erase a key from the map.
246 /// Erase a key from the map. It called by the observer notifier
247 /// and it overrides the erase() member function of the observer base.
248 virtual void erase(const Key& key) {
249 int id = Parent::getNotifier()->id(key);
250 allocator.destroy(&(values[id]));
253 /// \brief Erase more keys from the map.
255 /// Erase more keys from the map. It called by the observer notifier
256 /// and it overrides the erase() member function of the observer base.
257 virtual void erase(const std::vector<Key>& keys) {
258 for (int i = 0; i < (int)keys.size(); ++i) {
259 int id = Parent::getNotifier()->id(keys[i]);
260 allocator.destroy(&(values[id]));
264 /// \brief Buildes the map.
266 /// It buildes the map. It called by the observer notifier
267 /// and it overrides the build() member function of the observer base.
268 virtual void build() {
269 Notifier* notifier = Parent::getNotifier();
272 for (notifier->first(it); it != INVALID; notifier->next(it)) {
273 int id = notifier->id(it);;
274 allocator.construct(&(values[id]), Value());
278 /// \brief Clear the map.
280 /// It erase all items from the map. It called by the observer notifier
281 /// and it overrides the clear() member function of the observer base.
282 virtual void clear() {
283 Notifier* notifier = Parent::getNotifier();
286 for (notifier->first(it); it != INVALID; notifier->next(it)) {
287 int id = notifier->id(it);
288 allocator.destroy(&(values[id]));
290 allocator.deallocate(values, capacity);
297 void allocate_memory() {
298 int max_id = Parent::getNotifier()->maxId();
305 while (capacity <= max_id) {
308 values = allocator.allocate(capacity);