The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.
The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.
The ResGraphAdaptor is based on this composition.
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_ARRAY_MAP_H
20 #define LEMON_ARRAY_MAP_H
23 #include <lemon/bits/map_extender.h>
24 #include <lemon/bits/alteration_notifier.h>
25 #include <lemon/concept_check.h>
26 #include <lemon/concept/maps.h>
28 /// \ingroup graphmapfactory
30 /// \brief Graph maps that construct and destruct
31 /// their elements dynamically.
35 /// \ingroup graphmapfactory
37 /// \brief Graph map based on the array storage.
39 /// The ArrayMap template class is graph map structure what
40 /// automatically indates the map when a key is added to or erased from
41 /// the map. This map uses the allocators to implement
42 /// the container functionality.
44 /// The template parameter is the AlterationNotifier that the maps
45 /// will belong to and the Value.
47 template <typename _Graph,
50 class ArrayMap : public AlterationNotifier<_Item>::ObserverBase {
54 /// The graph type of the maps.
56 /// The reference map tag.
57 typedef True ReferenceMapTag;
59 /// The key type of the maps.
61 /// The value type of the map.
63 /// The const reference type of the map.
64 typedef const _Value& ConstReference;
65 /// The reference type of the map.
66 typedef _Value& Reference;
68 typedef const Value ConstValue;
69 typedef Value* Pointer;
70 typedef const Value* ConstPointer;
72 typedef AlterationNotifier<_Item> Registry;
74 /// The MapBase of the Map which imlements the core regisitry function.
75 typedef typename Registry::ObserverBase Parent;
80 typedef std::allocator<Value> Allocator;
85 /// \brief Graph initialized map constructor.
87 /// Graph initialized map constructor.
88 ArrayMap(const Graph& _g) : graph(&_g) {
90 attach(_g.getNotifier(Item()));
92 for (graph->first(it); it != INVALID; graph->next(it)) {
93 int id = graph->id(it);;
94 allocator.construct(&(values[id]), Value());
98 /// \brief Constructor to use default value to initialize the map.
100 /// It constructs a map and initialize all of the the map.
101 ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) {
103 attach(_g.getNotifier(_Item()));
105 for (graph->first(it); it != INVALID; graph->next(it)) {
106 int id = graph->id(it);;
107 allocator.construct(&(values[id]), _v);
111 /// \brief Constructor to copy a map of the same map type.
113 /// Constructor to copy a map of the same map type.
114 ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) {
115 if (copy.attached()) {
116 attach(*copy.getRegistry());
118 capacity = copy.capacity;
119 if (capacity == 0) return;
120 values = allocator.allocate(capacity);
122 for (graph->first(it); it != INVALID; graph->next(it)) {
123 int id = graph->id(it);;
124 allocator.construct(&(values[id]), copy.values[id]);
128 /// \brief The destructor of the map.
130 /// The destructor of the map.
131 virtual ~ArrayMap() {
140 ArrayMap& operator=(const ArrayMap&);
144 using Parent::attach;
145 using Parent::detach;
146 using Parent::attached;
148 const Graph* getGraph() {
155 /// \brief The subscript operator.
157 /// The subscript operator. The map can be subscripted by the
158 /// actual keys of the graph.
159 Value& operator[](const Key& key) {
160 int id = graph->id(key);
164 /// \brief The const subscript operator.
166 /// The const subscript operator. The map can be subscripted by the
167 /// actual keys of the graph.
168 const Value& operator[](const Key& key) const {
169 int id = graph->id(key);
173 /// \brief Setter function of the map.
175 /// Setter function of the map. Equivalent with map[key] = val.
176 /// This is a compatibility feature with the not dereferable maps.
177 void set(const Key& key, const Value& val) {
183 /// Add a new key to the map. It called by the map registry.
185 virtual void add(const Key& key) {
186 int id = graph->id(key);
187 if (id >= capacity) {
188 int new_capacity = (capacity == 0 ? 1 : capacity);
189 while (new_capacity <= id) {
192 Value* new_values = allocator.allocate(new_capacity);
194 for (graph->first(it); it != INVALID; graph->next(it)) {
195 int jd = graph->id(it);;
197 allocator.construct(&(new_values[jd]), values[jd]);
198 allocator.destroy(&(values[jd]));
201 if (capacity != 0) allocator.deallocate(values, capacity);
203 capacity = new_capacity;
205 allocator.construct(&(values[id]), Value());
208 virtual void add(const std::vector<Key>& keys) {
210 for (int i = 0; i < (int)keys.size(); ++i) {
211 int id = graph->id(keys[i]);
216 if (max_id >= capacity) {
217 int new_capacity = (capacity == 0 ? 1 : capacity);
218 while (new_capacity <= max_id) {
221 Value* new_values = allocator.allocate(new_capacity);
223 for (graph->first(it); it != INVALID; graph->next(it)) {
224 int id = graph->id(it);
226 for (int i = 0; i < (int)keys.size(); ++i) {
227 int jd = graph->id(keys[i]);
234 allocator.construct(&(new_values[id]), values[id]);
235 allocator.destroy(&(values[id]));
237 if (capacity != 0) allocator.deallocate(values, capacity);
239 capacity = new_capacity;
241 for (int i = 0; i < (int)keys.size(); ++i) {
242 int id = graph->id(keys[i]);
243 allocator.construct(&(values[id]), Value());
247 /// Erase a key from the map. It called by the map registry.
249 virtual void erase(const Key& key) {
250 int id = graph->id(key);
251 allocator.destroy(&(values[id]));
254 virtual void erase(const std::vector<Key>& keys) {
255 for (int i = 0; i < (int)keys.size(); ++i) {
256 int id = graph->id(keys[i]);
257 allocator.destroy(&(values[id]));
261 virtual void build() {
264 for (graph->first(it); it != INVALID; graph->next(it)) {
265 int id = graph->id(it);;
266 allocator.construct(&(values[id]), Value());
270 virtual void clear() {
273 for (graph->first(it); it != INVALID; graph->next(it)) {
274 int id = graph->id(it);
275 allocator.destroy(&(values[id]));
277 allocator.deallocate(values, capacity);
284 void allocate_memory() {
285 int max_id = graph->maxId(_Item());
292 while (capacity <= max_id) {
295 values = allocator.allocate(capacity);
307 #endif //LEMON_ARRAY_MAP_H