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