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 {
51 typedef True AdaptibleTag;
53 /// The graph type of the maps.
55 /// The key type of the maps.
58 typedef AlterationNotifier<_Item> Registry;
60 /// The MapBase of the Map which imlements the core regisitry function.
61 typedef typename Registry::ObserverBase Parent;
63 /// The value type of the map.
68 typedef std::allocator<Value> Allocator;
73 /// \brief Graph and Registry initialized map constructor.
75 /// Graph and Registry initialized map constructor.
76 ArrayMap(const Graph& _g) : graph(&_g) {
78 attach(_g.getNotifier(Item()));
80 for (graph->first(it); it != INVALID; graph->next(it)) {
81 int id = graph->id(it);;
82 allocator.construct(&(values[id]), Value());
86 /// \brief Constructor to use default value to initialize the map.
88 /// It constructs a map and initialize all of the the map.
89 ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
91 attach(_g.getNotifier(_Item()));
93 for (graph->first(it); it != INVALID; graph->next(it)) {
94 int id = graph->id(it);;
95 allocator.construct(&(values[id]), _v);
99 /// \brief Constructor to copy a map of the same map type.
101 /// Constructor to copy a map of the same map type.
102 ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) {
103 if (copy.attached()) {
104 attach(*copy.getRegistry());
106 capacity = copy.capacity;
107 if (capacity == 0) return;
108 values = allocator.allocate(capacity);
110 for (graph->first(it); it != INVALID; graph->next(it)) {
111 int id = graph->id(it);;
112 allocator.construct(&(values[id]), copy.values[id]);
116 /// \brief The destructor of the map.
118 /// The destructor of the map.
119 virtual ~ArrayMap() {
128 ArrayMap& operator=(const ArrayMap&);
132 using Parent::attach;
133 using Parent::detach;
134 using Parent::attached;
136 const Graph* getGraph() {
143 /// \brief The subscript operator.
145 /// The subscript operator. The map can be subscripted by the
146 /// actual keys of the graph.
147 Value& operator[](const Key& key) {
148 int id = graph->id(key);
152 /// \brief The const subscript operator.
154 /// The const subscript operator. The map can be subscripted by the
155 /// actual keys of the graph.
156 const Value& operator[](const Key& key) const {
157 int id = graph->id(key);
161 /// \brief Setter function of the map.
163 /// Setter function of the map. Equivalent with map[key] = val.
164 /// This is a compatibility feature with the not dereferable maps.
165 void set(const Key& key, const Value& val) {
171 /// Add a new key to the map. It called by the map registry.
173 virtual void add(const Key& key) {
174 int id = graph->id(key);
175 if (id >= capacity) {
176 int new_capacity = (capacity == 0 ? 1 : capacity);
177 while (new_capacity <= id) {
180 Value* new_values = allocator.allocate(new_capacity);
182 for (graph->first(it); it != INVALID; graph->next(it)) {
183 int jd = graph->id(it);;
185 allocator.construct(&(new_values[jd]), values[jd]);
186 allocator.destroy(&(values[jd]));
189 if (capacity != 0) allocator.deallocate(values, capacity);
191 capacity = new_capacity;
193 allocator.construct(&(values[id]), Value());
196 virtual void add(const std::vector<Key>& keys) {
198 for (int i = 0; i < (int)keys.size(); ++i) {
199 int id = graph->id(keys[i]);
204 if (max_id >= capacity) {
205 int new_capacity = (capacity == 0 ? 1 : capacity);
206 while (new_capacity <= max_id) {
209 Value* new_values = allocator.allocate(new_capacity);
211 for (graph->first(it); it != INVALID; graph->next(it)) {
212 int id = graph->id(it);
214 for (int i = 0; i < (int)keys.size(); ++i) {
215 int jd = graph->id(keys[i]);
222 allocator.construct(&(new_values[id]), values[id]);
223 allocator.destroy(&(values[id]));
225 if (capacity != 0) allocator.deallocate(values, capacity);
227 capacity = new_capacity;
229 for (int i = 0; i < (int)keys.size(); ++i) {
230 int id = graph->id(keys[i]);
231 allocator.construct(&(values[id]), Value());
235 /// Erase a key from the map. It called by the map registry.
237 virtual void erase(const Key& key) {
238 int id = graph->id(key);
239 allocator.destroy(&(values[id]));
242 virtual void erase(const std::vector<Key>& keys) {
243 for (int i = 0; i < (int)keys.size(); ++i) {
244 int id = graph->id(keys[i]);
245 allocator.destroy(&(values[id]));
249 virtual void build() {
252 for (graph->first(it); it != INVALID; graph->next(it)) {
253 int id = graph->id(it);;
254 allocator.construct(&(values[id]), Value());
258 virtual void clear() {
261 for (graph->first(it); it != INVALID; graph->next(it)) {
262 int id = graph->id(it);
263 allocator.destroy(&(values[id]));
265 allocator.deallocate(values, capacity);
272 void allocate_memory() {
273 int max_id = graph->maxId(_Item());
280 while (capacity <= max_id) {
283 values = allocator.allocate(capacity);
295 #endif //LEMON_ARRAY_MAP_H