Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

alteration_notifier.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/notifier.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00017 #ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
00018 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
00019 
00020 #include <vector>
00021 #include <algorithm>
00022 
00026 
00027 namespace lemon {
00028 
00031 
00048 
00049   template <typename _Item>
00050   class AlterationNotifier {
00051   public:
00052     typedef _Item Item;
00053 
00055         
00070 
00071     class ObserverBase {
00072     protected:
00073       typedef AlterationNotifier Registry;
00074 
00075       friend class AlterationNotifier;
00076 
00081       ObserverBase() : registry(0) {}
00082 
00083       virtual ~ObserverBase() {}
00084 
00089       void attach(AlterationNotifier& r) {
00090         registry = &r;
00091         registry->attach(*this);
00092       }
00093 
00098       void detach() {
00099         if (registry) {
00100           registry->detach(*this);
00101         }
00102       }
00103         
00104 
00106 
00110       Registry* getRegistry() const { return const_cast<Registry*>(registry); }
00111       
00113       bool attached() const { return registry != 0; }
00114         
00115     private:
00116 
00117       ObserverBase(const ObserverBase& copy);
00118       ObserverBase& operator=(const ObserverBase& copy);
00119 
00120     protected:
00121       
00122       Registry* registry;
00123       int registry_index;
00124 
00125     public:
00126 
00133         
00134       virtual void add(const Item&) = 0;
00135 
00142 
00143       virtual void add(const std::vector<Item>& items) {
00144         for (int i = 0; i < (int)items.size(); ++i) {
00145           add(items[i]);
00146         }
00147       }
00148 
00155         
00156       virtual void erase(const Item&) = 0;
00157 
00158       virtual void erase(const std::vector<Item>& items) {
00159         for (int i = 0; i < (int)items.size(); ++i) {
00160           add(items[i]);
00161         }
00162       }
00163 
00170 
00171       virtual void build() = 0;
00172 
00179       
00180       virtual void clear() = 0;
00181 
00182     };
00183         
00184   protected:
00185         
00186 
00187     typedef std::vector<ObserverBase*> Container; 
00188 
00189     Container container;
00190 
00191                 
00192   public:
00193 
00195         
00199     AlterationNotifier() {}
00200 
00202         
00206     AlterationNotifier(const AlterationNotifier&) {}
00207 
00209                 
00213     AlterationNotifier& operator=(const AlterationNotifier&) {
00214       typename Container::iterator it;
00215       for (it = container.begin(); it != container.end(); ++it) {
00216         (*it)->registry = 0;
00217       }
00218     }
00219 
00221                                 
00224     ~AlterationNotifier() {
00225       typename Container::iterator it;
00226       for (it = container.begin(); it != container.end(); ++it) {
00227         (*it)->registry = 0;
00228       }
00229     }
00230         
00231         
00232   protected:
00233 
00234     void attach(ObserverBase& observer) {
00235       container.push_back(&observer);
00236       observer.registry = this;
00237       observer.registry_index = container.size()-1;
00238     } 
00239 
00240     void detach(ObserverBase& base) {
00241       container.back()->registry_index = base.registry_index; 
00242       container[base.registry_index] = container.back();
00243       container.pop_back();
00244       base.registry = 0;
00245     }
00246 
00247   public:
00248         
00255     void add(const Item& item) {
00256       typename Container::iterator it;
00257       for (it = container.begin(); it != container.end(); ++it) {
00258         (*it)->add(item);
00259       }
00260     }   
00261 
00268     void add(const std::vector<Item>& items) {
00269       typename Container::iterator it;
00270       for (it = container.begin(); it != container.end(); ++it) {
00271         (*it)->add(items);
00272       }
00273     }   
00274 
00281     void erase(const Item& key) {
00282       typename Container::iterator it;
00283       for (it = container.begin(); it != container.end(); ++it) {
00284         (*it)->erase(key);
00285       }
00286     }
00287 
00294     void erase(const std::vector<Item>& items) {
00295       typename Container::iterator it;
00296       for (it = container.begin(); it != container.end(); ++it) {
00297         (*it)->erase(items);
00298       }
00299     }
00300     
00301 
00307     void build() {
00308       typename Container::iterator it;
00309       for (it = container.begin(); it != container.end(); ++it) {
00310         (*it)->build();
00311       }
00312     }
00313 
00314 
00320     void clear() {
00321       typename Container::iterator it;
00322       for (it = container.begin(); it != container.end(); ++it) {
00323         (*it)->clear();
00324       }
00325     }
00326   };
00327 
00328 
00347 
00348   template <typename _Base> 
00349   class AlterableGraphExtender : public _Base {
00350   public:
00351 
00352     typedef AlterableGraphExtender Graph;
00353     typedef _Base Parent;
00354 
00355     typedef typename Parent::Node Node;
00356     typedef typename Parent::Edge Edge;
00357 
00359     typedef AlterationNotifier<Edge> EdgeNotifier;
00361     typedef AlterationNotifier<Node> NodeNotifier;
00362 
00363 
00364   protected:
00365 
00366     mutable EdgeNotifier edge_notifier;
00367 
00368     mutable NodeNotifier node_notifier;
00369 
00370   public:
00371 
00375     EdgeNotifier& getNotifier(Edge) const {
00376       return edge_notifier;
00377     }
00378 
00382     NodeNotifier& getNotifier(Node) const {
00383       return node_notifier;
00384     }
00385 
00386     ~AlterableGraphExtender() {
00387       node_notifier.clear();
00388       edge_notifier.clear();
00389     }
00390     
00391   };
00392 
00403 
00404   template <typename _Base> 
00405   class AlterableUndirGraphExtender
00406     : public AlterableGraphExtender<_Base> {
00407   public:
00408 
00409     typedef AlterableUndirGraphExtender Graph;
00410     typedef AlterableGraphExtender<_Base> Parent;
00411 
00412     typedef typename Parent::UndirEdge UndirEdge;
00413 
00415     typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
00416 
00417   protected:
00418 
00419     mutable UndirEdgeNotifier undir_edge_notifier;
00420 
00421   public:
00422 
00423     using Parent::getNotifier;
00424     UndirEdgeNotifier& getNotifier(UndirEdge) const {
00425       return undir_edge_notifier;
00426     }
00427 
00428     ~AlterableUndirGraphExtender() {
00429       undir_edge_notifier.clear();
00430     }
00431   };
00432   
00434   
00435 
00436 }
00437 
00438 #endif

Generated on Sat Aug 27 14:14:50 2005 for LEMON by  doxygen 1.4.4