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  * src/lemon/notifier.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Combinatorial Optimization Research Group, 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 using namespace std;
00028 
00029 namespace lemon {
00030 
00033 
00035 
00050 
00051   template <typename _Item>
00052   class AlterationNotifier {
00053   public:
00054     typedef _Item Item;
00055 
00057         
00072 
00073     class ObserverBase {
00074     protected:
00075       typedef AlterationNotifier Registry;
00076 
00077       friend class AlterationNotifier;
00078 
00080 
00083       ObserverBase() : registry(0) {}
00084 
00085       virtual ~ObserverBase() {}
00086 
00088 
00091       void attach(AlterationNotifier& r) {
00092         registry = &r;
00093         registry->attach(*this);
00094       }
00095 
00097 
00100       void detach() {
00101         if (registry) {
00102           registry->detach(*this);
00103         }
00104       }
00105         
00106 
00108 
00112       Registry* getRegistry() const { return const_cast<Registry*>(registry); }
00113       
00115       bool attached() const { return registry != 0; }
00116         
00117     private:
00118 
00119       ObserverBase(const ObserverBase& copy);
00120       ObserverBase& operator=(const ObserverBase& copy);
00121 
00122     protected:
00123       
00124       Registry* registry;
00125       int registry_index;
00126 
00127     public:
00128 
00135         
00136       virtual void add(const Item&) = 0;        
00137 
00138 
00145         
00146       virtual void erase(const Item&) = 0;
00147 
00154 
00155       virtual void build() = 0;
00156 
00163       
00164       virtual void clear() = 0;
00165 
00166     };
00167         
00168   protected:
00169         
00170 
00171     typedef std::vector<ObserverBase*> Container; 
00172 
00173     Container container;
00174 
00175                 
00176   public:
00177 
00179         
00183     AlterationNotifier() {}
00184 
00186         
00190     AlterationNotifier(const AlterationNotifier&) {}
00191 
00193                 
00197     AlterationNotifier& operator=(const AlterationNotifier&) {
00198       typename Container::iterator it;
00199       for (it = container.begin(); it != container.end(); ++it) {
00200         (*it)->registry = 0;
00201       }
00202     }
00203 
00205                                 
00208     ~AlterationNotifier() {
00209       typename Container::iterator it;
00210       for (it = container.begin(); it != container.end(); ++it) {
00211         (*it)->registry = 0;
00212       }
00213     }
00214         
00215         
00216   protected:
00217 
00218     void attach(ObserverBase& observer) {
00219       container.push_back(&observer);
00220       observer.registry = this;
00221       observer.registry_index = container.size()-1;
00222     } 
00223 
00224     void detach(ObserverBase& base) {
00225       container.back()->registry_index = base.registry_index; 
00226       container[base.registry_index] = container.back();
00227       container.pop_back();
00228       base.registry = 0;
00229     }
00230 
00231   public:
00232         
00234                 
00237     void add(const Item& key) {
00238       typename Container::iterator it;
00239       for (it = container.begin(); it != container.end(); ++it) {
00240         (*it)->add(key);
00241       }
00242     }   
00243 
00245                 
00248     void erase(const Item& key) {
00249       typename Container::iterator it;
00250       for (it = container.begin(); it != container.end(); ++it) {
00251         (*it)->erase(key);
00252       }
00253     }
00254     
00255 
00257                 
00260     void build() {
00261       typename Container::iterator it;
00262       for (it = container.begin(); it != container.end(); ++it) {
00263         (*it)->build();
00264       }
00265     }
00266 
00267 
00269 
00272     void clear() {
00273       typename Container::iterator it;
00274       for (it = container.begin(); it != container.end(); ++it) {
00275         (*it)->clear();
00276       }
00277     }
00278   };
00279 
00280 
00299 
00300   template <typename _Base> 
00301   class AlterableGraphExtender : public _Base {
00302   public:
00303 
00304     typedef AlterableGraphExtender Graph;
00305     typedef _Base Parent;
00306 
00307     typedef typename Parent::Node Node;
00308     typedef typename Parent::Edge Edge;
00309 
00311     typedef AlterationNotifier<Edge> EdgeNotifier;
00313     typedef AlterationNotifier<Node> NodeNotifier;
00314 
00315 
00316   protected:
00317 
00318     mutable EdgeNotifier edge_notifier;
00319 
00320     mutable NodeNotifier node_notifier;
00321 
00322   public:
00323 
00327     EdgeNotifier& getNotifier(Edge) const {
00328       return edge_notifier;
00329     }
00330 
00334     NodeNotifier& getNotifier(Node) const {
00335       return node_notifier;
00336     }
00337 
00338     ~AlterableGraphExtender() {
00339       node_notifier.clear();
00340       edge_notifier.clear();
00341     }
00342     
00343   };
00344 
00355 
00356   template <typename _Base> 
00357   class AlterableUndirGraphExtender
00358     : public AlterableGraphExtender<_Base> {
00359   public:
00360 
00361     typedef AlterableUndirGraphExtender Graph;
00362     typedef AlterableGraphExtender<_Base> Parent;
00363 
00364     typedef typename Parent::UndirEdge UndirEdge;
00365 
00367     typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
00368 
00369   protected:
00370 
00371     mutable UndirEdgeNotifier undir_edge_notifier;
00372 
00373   public:
00374 
00375     using Parent::getNotifier;
00376     UndirEdgeNotifier& getNotifier(UndirEdge) const {
00377       return undir_edge_notifier;
00378     }
00379 
00380     ~AlterableUndirGraphExtender() {
00381       undir_edge_notifier.clear();
00382     }
00383   };
00384   
00386   
00387 
00388 }
00389 
00390 #endif

Generated on Sat Mar 19 10:58:39 2005 for LEMON by  doxygen 1.4.1