alteration_notifier.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  *
00003  * This file is a part of LEMON, a generic C++ optimization library
00004  *
00005  * Copyright (C) 2003-2006
00006  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00007  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00008  *
00009  * Permission to use, modify and distribute this software is granted
00010  * provided that this copyright notice appears in all copies. For
00011  * precise terms see the accompanying LICENSE file.
00012  *
00013  * This software is provided "AS IS" with no warranty of any kind,
00014  * express or implied, and with no claim as to its suitability for any
00015  * purpose.
00016  *
00017  */
00018 
00019 #ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
00020 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
00021 
00022 #include <vector>
00023 #include <algorithm>
00024 
00028 
00029 namespace lemon {
00030 
00033 
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 
00083       ObserverBase() : registry(0) {}
00084 
00085       ObserverBase(const ObserverBase& copy) {
00086         if (copy.attached()) {
00087           copy.getRegistry()->attach(*this);
00088         }
00089       }
00090         
00091       virtual ~ObserverBase() {}
00092 
00097       void attach(AlterationNotifier& r) {
00098         registry = &r;
00099         registry->attach(*this);
00100       }
00101 
00106       void detach() {
00107         if (registry) {
00108           registry->detach(*this);
00109         }
00110       }
00111         
00112 
00114 
00118       Registry* getRegistry() const { return const_cast<Registry*>(registry); }
00119       
00121       bool attached() const { return registry != 0; }
00122 
00123     private:
00124 
00125       ObserverBase& operator=(const ObserverBase& copy);
00126 
00127     protected:
00128       
00129       Registry* registry;
00130       int registry_index;
00131 
00138         
00139       virtual void add(const Item&) = 0;
00140 
00147 
00148       virtual void add(const std::vector<Item>& items) {
00149         for (int i = 0; i < (int)items.size(); ++i) {
00150           add(items[i]);
00151         }
00152       }
00153 
00160         
00161       virtual void erase(const Item&) = 0;
00162 
00169       virtual void erase(const std::vector<Item>& items) {
00170         for (int i = 0; i < (int)items.size(); ++i) {
00171           erase(items[i]);
00172         }
00173       }
00174 
00181 
00182       virtual void build() = 0;
00183 
00190       
00191       virtual void clear() = 0;
00192 
00193     };
00194         
00195   protected:
00196         
00197 
00198     typedef std::vector<ObserverBase*> Container; 
00199 
00200     Container container;
00201 
00202                 
00203   public:
00204 
00206         
00210     AlterationNotifier() {}
00211 
00213         
00217     AlterationNotifier(const AlterationNotifier&) {}
00218 
00220                 
00224     AlterationNotifier& operator=(const AlterationNotifier&) {
00225       typename Container::iterator it;
00226       for (it = container.begin(); it != container.end(); ++it) {
00227         (*it)->registry = 0;
00228       }
00229     }
00230 
00232                                 
00235     ~AlterationNotifier() {
00236       typename Container::iterator it;
00237       for (it = container.begin(); it != container.end(); ++it) {
00238         (*it)->registry = 0;
00239       }
00240     }
00241         
00242         
00243   protected:
00244 
00245     void attach(ObserverBase& observer) {
00246       container.push_back(&observer);
00247       observer.registry = this;
00248       observer.registry_index = container.size()-1;
00249     } 
00250 
00251     void detach(ObserverBase& base) {
00252       container.back()->registry_index = base.registry_index; 
00253       container[base.registry_index] = container.back();
00254       container.pop_back();
00255       base.registry = 0;
00256     }
00257 
00258   public:
00259         
00266     void add(const Item& item) {
00267       typename Container::iterator it;
00268       for (it = container.begin(); it != container.end(); ++it) {
00269         (*it)->add(item);
00270       }
00271     }   
00272 
00279     void add(const std::vector<Item>& items) {
00280       typename Container::iterator it;
00281       for (it = container.begin(); it != container.end(); ++it) {
00282         (*it)->add(items);
00283       }
00284     }   
00285 
00292     void erase(const Item& key) {
00293       typename Container::iterator it;
00294       for (it = container.begin(); it != container.end(); ++it) {
00295         (*it)->erase(key);
00296       }
00297     }
00298 
00305     void erase(const std::vector<Item>& items) {
00306       typename Container::iterator it;
00307       for (it = container.begin(); it != container.end(); ++it) {
00308         (*it)->erase(items);
00309       }
00310     }
00311 
00317     void build() {
00318       typename Container::iterator it;
00319       for (it = container.begin(); it != container.end(); ++it) {
00320         (*it)->build();
00321       }
00322     }
00323 
00324 
00330     void clear() {
00331       typename Container::iterator it;
00332       for (it = container.begin(); it != container.end(); ++it) {
00333         (*it)->clear();
00334       }
00335     }
00336   };
00337 
00338 
00357 
00358   template <typename _Base> 
00359   class AlterableGraphExtender : public _Base {
00360   public:
00361 
00362     typedef AlterableGraphExtender Graph;
00363     typedef _Base Parent;
00364 
00365     typedef typename Parent::Node Node;
00366     typedef typename Parent::Edge Edge;
00367 
00369     typedef AlterationNotifier<Edge> EdgeNotifier;
00371     typedef AlterationNotifier<Node> NodeNotifier;
00372 
00373 
00374   protected:
00375 
00376     mutable EdgeNotifier edge_notifier;
00377 
00378     mutable NodeNotifier node_notifier;
00379 
00380   public:
00381 
00385     EdgeNotifier& getNotifier(Edge) const {
00386       return edge_notifier;
00387     }
00388 
00392     NodeNotifier& getNotifier(Node) const {
00393       return node_notifier;
00394     }
00395 
00396     ~AlterableGraphExtender() {
00397       node_notifier.clear();
00398       edge_notifier.clear();
00399     }
00400     
00401   };
00402 
00403 
00404   template <typename _Base> 
00405   class AlterableEdgeSetExtender : public _Base {
00406   public:
00407 
00408     typedef AlterableEdgeSetExtender Graph;
00409     typedef _Base Parent;
00410 
00411     typedef typename Parent::Edge Edge;
00412 
00414     typedef AlterationNotifier<Edge> EdgeNotifier;
00415 
00416   protected:
00417 
00418     mutable EdgeNotifier edge_notifier;
00419 
00420   public:
00421 
00425     EdgeNotifier& getNotifier(Edge) const {
00426       return edge_notifier;
00427     }
00428 
00429     ~AlterableEdgeSetExtender() {
00430       edge_notifier.clear();
00431     }
00432     
00433   };
00434 
00445 
00446   template <typename _Base> 
00447   class AlterableUGraphExtender
00448     : public AlterableGraphExtender<_Base> {
00449   public:
00450 
00451     typedef AlterableUGraphExtender Graph;
00452     typedef AlterableGraphExtender<_Base> Parent;
00453 
00454     typedef typename Parent::UEdge UEdge;
00455 
00457     typedef AlterationNotifier<UEdge> UEdgeNotifier;
00458 
00459   protected:
00460 
00461     mutable UEdgeNotifier u_edge_notifier;
00462 
00463   public:
00464 
00465     using Parent::getNotifier;
00466     UEdgeNotifier& getNotifier(UEdge) const {
00467       return u_edge_notifier;
00468     }
00469 
00470     ~AlterableUGraphExtender() {
00471       u_edge_notifier.clear();
00472     }
00473   };
00474 
00475   template <typename _Base> 
00476   class AlterableUEdgeSetExtender
00477     : public AlterableEdgeSetExtender<_Base> {
00478   public:
00479 
00480     typedef AlterableUEdgeSetExtender Graph;
00481     typedef AlterableEdgeSetExtender<_Base> Parent;
00482 
00483     typedef typename Parent::UEdge UEdge;
00484 
00485     typedef AlterationNotifier<UEdge> UEdgeNotifier;
00486 
00487   protected:
00488 
00489     mutable UEdgeNotifier u_edge_notifier;
00490 
00491   public:
00492 
00493     using Parent::getNotifier;
00494     UEdgeNotifier& getNotifier(UEdge) const {
00495       return u_edge_notifier;
00496     }
00497 
00498     ~AlterableUEdgeSetExtender() {
00499       u_edge_notifier.clear();
00500     }
00501   };
00502 
00503 
00504 
00505   template <typename _Base>
00506   class AlterableBpUGraphExtender : public _Base {
00507   public:
00508 
00509     typedef _Base Parent;
00510     typedef AlterableBpUGraphExtender Graph;
00511   
00512     typedef typename Parent::Node Node;
00513     typedef typename Parent::BNode BNode;
00514     typedef typename Parent::ANode ANode;
00515     typedef typename Parent::Edge Edge;
00516     typedef typename Parent::UEdge UEdge;
00517   
00518   
00519     typedef AlterationNotifier<Node> NodeNotifier;
00520     typedef AlterationNotifier<BNode> BNodeNotifier;
00521     typedef AlterationNotifier<ANode> ANodeNotifier;
00522     typedef AlterationNotifier<Edge> EdgeNotifier;
00523     typedef AlterationNotifier<UEdge> UEdgeNotifier;
00524 
00525   protected:
00526 
00527     mutable NodeNotifier nodeNotifier;
00528     mutable BNodeNotifier bNodeNotifier;
00529     mutable ANodeNotifier aNodeNotifier;
00530     mutable EdgeNotifier edgeNotifier;
00531     mutable UEdgeNotifier uEdgeNotifier;
00532 
00533   public:
00534 
00535     NodeNotifier& getNotifier(Node) const {
00536       return nodeNotifier;
00537     }
00538 
00539     BNodeNotifier& getNotifier(BNode) const {
00540       return bNodeNotifier;
00541     }
00542 
00543     ANodeNotifier& getNotifier(ANode) const {
00544       return aNodeNotifier;
00545     }
00546 
00547     EdgeNotifier& getNotifier(Edge) const {
00548       return edgeNotifier;
00549     }
00550 
00551     UEdgeNotifier& getNotifier(UEdge) const {
00552       return uEdgeNotifier;
00553     }
00554 
00555     ~AlterableBpUGraphExtender() {
00556       nodeNotifier.clear();
00557       bNodeNotifier.clear();
00558       aNodeNotifier.clear();
00559       edgeNotifier.clear();
00560       uEdgeNotifier.clear();
00561     }
00562 
00563   };
00564   
00566   
00567 
00568 }
00569 
00570 #endif

Generated on Fri Feb 3 18:35:35 2006 for LEMON by  doxygen 1.4.6