| author | alpar | 
| Sat, 29 Jan 2005 23:22:56 +0000 | |
| changeset 1109 | 5222b3d588c3 | 
| 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  |