author | alpar |
Mon, 21 Mar 2005 11:40:08 +0000 | |
changeset 1233 | f3d856bf1ebf |
parent 703 | 32f280a5ed7d |
permissions | -rw-r--r-- |
deba@378 | 1 |
#ifndef MAP_REGISTRY_H |
deba@378 | 2 |
#define MAP_REGISTRY_H |
deba@378 | 3 |
|
deba@378 | 4 |
#include <vector> |
deba@378 | 5 |
|
deba@595 | 6 |
using namespace std; |
deba@595 | 7 |
|
alpar@921 | 8 |
namespace lemon { |
alpar@676 | 9 |
|
deba@627 | 10 |
/** |
deba@701 | 11 |
* Registry class to register edge or node maps into the graph. The |
deba@701 | 12 |
* registry helps you to implement an observer pattern. If you add |
deba@701 | 13 |
* or erase an edge or node you must notify all the maps about the |
deba@701 | 14 |
* event. |
deba@627 | 15 |
*/ |
deba@627 | 16 |
template <typename G, typename K, typename KIt> |
deba@627 | 17 |
class MapRegistry { |
deba@627 | 18 |
public: |
deba@627 | 19 |
typedef G Graph; |
deba@627 | 20 |
typedef K Key; |
deba@627 | 21 |
typedef KIt KeyIt; |
deba@378 | 22 |
|
deba@627 | 23 |
|
deba@627 | 24 |
|
deba@701 | 25 |
/** |
deba@701 | 26 |
* MapBase is the base class of the registered maps. |
deba@701 | 27 |
* It defines the core modification operations on the maps and |
deba@701 | 28 |
* implements some helper functions. |
deba@701 | 29 |
*/ |
deba@627 | 30 |
class MapBase { |
deba@627 | 31 |
public: |
deba@627 | 32 |
typedef G Graph; |
deba@627 | 33 |
typedef MapRegistry<G, K, KIt> Registry; |
deba@627 | 34 |
typedef K Key; |
deba@627 | 35 |
typedef KIt KeyIt; |
deba@378 | 36 |
|
deba@627 | 37 |
friend class Registry; |
deba@701 | 38 |
|
deba@701 | 39 |
/** |
deba@701 | 40 |
* Default constructor for MapBase. |
deba@701 | 41 |
*/ |
deba@701 | 42 |
|
deba@701 | 43 |
MapBase() : graph(0), registry(0) {} |
deba@627 | 44 |
|
deba@627 | 45 |
/** |
deba@701 | 46 |
* Simple constructor to register into a graph registry. |
deba@627 | 47 |
*/ |
deba@378 | 48 |
|
deba@701 | 49 |
MapBase(const Graph& g, Registry& r) : graph(&g), registry(0) { |
deba@627 | 50 |
r.attach(*this); |
deba@627 | 51 |
} |
deba@627 | 52 |
|
deba@627 | 53 |
/** |
deba@701 | 54 |
* Copy constructor to register into the registry. |
deba@627 | 55 |
*/ |
deba@627 | 56 |
|
deba@627 | 57 |
MapBase(const MapBase& copy) : registry(0), graph(copy.graph) { |
deba@627 | 58 |
if (copy.registry) { |
deba@627 | 59 |
copy.registry->attach(*this); |
deba@627 | 60 |
} |
deba@627 | 61 |
} |
deba@627 | 62 |
|
deba@627 | 63 |
/** |
deba@701 | 64 |
* Assign operator. |
deba@627 | 65 |
*/ |
deba@627 | 66 |
|
deba@627 | 67 |
const MapBase& operator=(const MapBase& copy) { |
deba@627 | 68 |
if (registry) { |
deba@627 | 69 |
registry->detach(*this); |
deba@627 | 70 |
} |
deba@627 | 71 |
graph = copy.graph; |
deba@627 | 72 |
if (copy.registry) { |
deba@627 | 73 |
copy.registry->attach(*this); |
deba@627 | 74 |
} |
deba@627 | 75 |
} |
deba@627 | 76 |
|
deba@627 | 77 |
|
deba@627 | 78 |
/** |
deba@701 | 79 |
* Destructor. |
deba@627 | 80 |
*/ |
deba@627 | 81 |
|
deba@627 | 82 |
virtual ~MapBase() { |
deba@627 | 83 |
if (registry) { |
deba@627 | 84 |
registry->detach(*this); |
deba@627 | 85 |
} |
deba@627 | 86 |
} |
deba@701 | 87 |
|
deba@701 | 88 |
/* |
deba@701 | 89 |
* Returns the graph that the map belongs to. |
deba@701 | 90 |
*/ |
deba@701 | 91 |
|
deba@701 | 92 |
const Graph* getGraph() const { return graph; } |
deba@627 | 93 |
|
deba@703 | 94 |
protected: |
deba@627 | 95 |
|
deba@703 | 96 |
const Graph* graph; |
deba@627 | 97 |
Registry* registry; |
deba@627 | 98 |
|
deba@627 | 99 |
int registry_index; |
deba@701 | 100 |
|
deba@701 | 101 |
protected: |
deba@627 | 102 |
|
deba@627 | 103 |
/** |
deba@627 | 104 |
Helper function to implement constructors in the subclasses. |
deba@627 | 105 |
*/ |
deba@627 | 106 |
|
deba@627 | 107 |
virtual void init() { |
deba@627 | 108 |
for (KeyIt it(*graph); graph->valid(it); graph->next(it)) { |
deba@627 | 109 |
add(it); |
deba@627 | 110 |
} |
deba@627 | 111 |
} |
deba@627 | 112 |
|
deba@627 | 113 |
/** |
deba@627 | 114 |
Helper function to implement the destructor in the subclasses. |
deba@627 | 115 |
*/ |
deba@627 | 116 |
|
deba@627 | 117 |
virtual void destroy() { |
deba@701 | 118 |
for (KeyIt it(*getGraph()); getGraph()->valid(it); getGraph()->next(it)) { |
deba@627 | 119 |
erase(it); |
deba@627 | 120 |
} |
deba@627 | 121 |
} |
deba@627 | 122 |
|
deba@627 | 123 |
/** |
deba@627 | 124 |
The add member function should be overloaded in the subclasses. |
deba@627 | 125 |
\e Add extends the map with the new node. |
deba@627 | 126 |
*/ |
deba@627 | 127 |
|
deba@627 | 128 |
virtual void add(const Key&) = 0; |
deba@627 | 129 |
/** |
deba@627 | 130 |
The erase member function should be overloaded in the subclasses. |
deba@627 | 131 |
\e Erase removes the node from the map. |
deba@627 | 132 |
*/ |
deba@627 | 133 |
|
deba@627 | 134 |
virtual void erase(const Key&) = 0; |
deba@627 | 135 |
|
deba@627 | 136 |
/** |
deba@627 | 137 |
Exception class to throw at unsupported operation. |
deba@627 | 138 |
*/ |
deba@627 | 139 |
|
deba@627 | 140 |
class NotSupportedOperationException {}; |
deba@627 | 141 |
|
deba@627 | 142 |
}; |
deba@627 | 143 |
|
deba@627 | 144 |
protected: |
deba@627 | 145 |
|
deba@701 | 146 |
/** |
deba@701 | 147 |
* The container type of the maps. |
deba@701 | 148 |
*/ |
deba@627 | 149 |
typedef std::vector<MapBase*> Container; |
deba@701 | 150 |
|
deba@701 | 151 |
/** |
deba@701 | 152 |
* The container of the registered maps. |
deba@701 | 153 |
*/ |
deba@627 | 154 |
Container container; |
deba@378 | 155 |
|
deba@378 | 156 |
|
deba@701 | 157 |
public: |
deba@378 | 158 |
|
deba@701 | 159 |
/** |
deba@701 | 160 |
* Default Constructor of the MapRegistry. It creates an empty registry. |
deba@701 | 161 |
*/ |
deba@627 | 162 |
MapRegistry() {} |
deba@571 | 163 |
|
deba@701 | 164 |
/** |
deba@701 | 165 |
* Copy Constructor of the MapRegistry. The new registry does not steal |
deba@701 | 166 |
* the maps from the right value. The new registry will be an empty. |
deba@701 | 167 |
*/ |
deba@627 | 168 |
MapRegistry(const MapRegistry&) {} |
deba@571 | 169 |
|
deba@701 | 170 |
/** |
deba@701 | 171 |
* Assign operator. The left value does not steal the maps |
deba@701 | 172 |
* from the right value. The left value will be an empty registry. |
deba@701 | 173 |
*/ |
deba@627 | 174 |
MapRegistry& operator=(const MapRegistry&) { |
deba@627 | 175 |
for (it = container.begin(); it != container.end(); ++it) { |
deba@627 | 176 |
(*it)->destroy(); |
deba@627 | 177 |
(*it)->graph = 0; |
deba@627 | 178 |
(*it)->registry = 0; |
deba@627 | 179 |
} |
deba@627 | 180 |
} |
deba@378 | 181 |
|
deba@701 | 182 |
/** |
deba@701 | 183 |
* Destructor of the MapRegistry. |
deba@701 | 184 |
*/ |
deba@627 | 185 |
~MapRegistry() { |
deba@627 | 186 |
typename Container::iterator it; |
deba@627 | 187 |
for (it = container.begin(); it != container.end(); ++it) { |
deba@627 | 188 |
(*it)->destroy(); |
deba@627 | 189 |
(*it)->registry = 0; |
deba@627 | 190 |
(*it)->graph = 0; |
deba@627 | 191 |
} |
deba@627 | 192 |
} |
deba@378 | 193 |
|
deba@378 | 194 |
|
deba@627 | 195 |
public: |
deba@378 | 196 |
|
deba@701 | 197 |
/** |
deba@701 | 198 |
* Attach a map into thr registry. If the map has been attached |
deba@701 | 199 |
* into an other registry it is detached from that automaticly. |
deba@701 | 200 |
*/ |
deba@627 | 201 |
void attach(MapBase& map) { |
deba@627 | 202 |
if (map.registry) { |
deba@627 | 203 |
map.registry->detach(map); |
deba@627 | 204 |
} |
deba@627 | 205 |
container.push_back(&map); |
deba@627 | 206 |
map.registry = this; |
deba@627 | 207 |
map.registry_index = container.size()-1; |
deba@627 | 208 |
} |
deba@378 | 209 |
|
deba@701 | 210 |
/** |
deba@701 | 211 |
* Detach the map from the registry. |
deba@701 | 212 |
*/ |
deba@627 | 213 |
void detach(MapBase& map) { |
deba@627 | 214 |
container.back()->registry_index = map.registry_index; |
deba@627 | 215 |
container[map.registry_index] = container.back(); |
deba@627 | 216 |
container.pop_back(); |
deba@627 | 217 |
map.registry = 0; |
deba@627 | 218 |
map.graph = 0; |
deba@627 | 219 |
} |
deba@378 | 220 |
|
deba@378 | 221 |
|
deba@701 | 222 |
/** |
deba@701 | 223 |
* Notify all the registered maps about a Key added. |
deba@701 | 224 |
*/ |
deba@627 | 225 |
virtual void add(Key& key) { |
deba@627 | 226 |
typename Container::iterator it; |
deba@627 | 227 |
for (it = container.begin(); it != container.end(); ++it) { |
deba@627 | 228 |
(*it)->add(key); |
deba@627 | 229 |
} |
deba@627 | 230 |
} |
deba@378 | 231 |
|
deba@701 | 232 |
/** |
deba@701 | 233 |
* Notify all the registered maps about a Key erased. |
deba@701 | 234 |
*/ |
deba@627 | 235 |
virtual void erase(Key& key) { |
deba@627 | 236 |
typename Container::iterator it; |
deba@627 | 237 |
for (it = container.begin(); it != container.end(); ++it) { |
deba@627 | 238 |
(*it)->erase(key); |
deba@627 | 239 |
} |
deba@627 | 240 |
} |
deba@378 | 241 |
|
deba@627 | 242 |
}; |
deba@378 | 243 |
|
deba@378 | 244 |
} |
deba@378 | 245 |
|
deba@378 | 246 |
#endif |