lemon/bits/alteration_notifier.h
changeset 1983 a60527609489
parent 1956 a055123339d5
child 1989 d276e88aa48a
equal deleted inserted replaced
13:4fe9055cefd6 14:9f8ad23552b5
   263     /// It notifies all the registered observers about an Item added to 
   263     /// It notifies all the registered observers about an Item added to 
   264     /// the container.
   264     /// the container.
   265     /// 
   265     /// 
   266     void add(const Item& item) {
   266     void add(const Item& item) {
   267       typename Container::iterator it;
   267       typename Container::iterator it;
   268       for (it = container.begin(); it != container.end(); ++it) {
   268       try {
   269 	(*it)->add(item);
   269         for (it = container.begin(); it != container.end(); ++it) {
       
   270           (*it)->add(item);
       
   271         }
       
   272       } catch (...) {
       
   273         typename Container::iterator jt;
       
   274         for (jt = container.begin(); jt != it; ++it) {
       
   275           (*it)->erase(item);
       
   276         }
       
   277         throw;
   270       }
   278       }
   271     }	
   279     }	
   272 
   280 
   273     /// \brief Notifies all the registered observers about more Item added to 
   281     /// \brief Notifies all the registered observers about more Item added to 
   274     /// the container.
   282     /// the container.
   276     /// It notifies all the registered observers about more Item added to 
   284     /// It notifies all the registered observers about more Item added to 
   277     /// the container.
   285     /// the container.
   278     /// 
   286     /// 
   279     void add(const std::vector<Item>& items) {
   287     void add(const std::vector<Item>& items) {
   280       typename Container::iterator it;
   288       typename Container::iterator it;
   281       for (it = container.begin(); it != container.end(); ++it) {
   289       try {
   282 	(*it)->add(items);
   290         for (it = container.begin(); it != container.end(); ++it) {
       
   291           (*it)->add(items);
       
   292         }
       
   293       } catch (...) {
       
   294         typename Container::iterator jt;
       
   295         for (jt = container.begin(); jt != it; ++it) {
       
   296           (*it)->erase(items);
       
   297         }
       
   298         throw;
   283       }
   299       }
   284     }	
   300     }	
   285 
   301 
   286     /// \brief Notifies all the registered observers about an Item erased from 
   302     /// \brief Notifies all the registered observers about an Item erased from 
   287     /// the container.
   303     /// the container.
   314     ///		
   330     ///		
   315     /// Notifies all the registered observers about the container is built
   331     /// Notifies all the registered observers about the container is built
   316     /// from an empty container.
   332     /// from an empty container.
   317     void build() {
   333     void build() {
   318       typename Container::iterator it;
   334       typename Container::iterator it;
   319       for (it = container.begin(); it != container.end(); ++it) {
   335       try {
   320 	(*it)->build();
   336         for (it = container.begin(); it != container.end(); ++it) {
       
   337           (*it)->build();
       
   338         }
       
   339       } catch (...) {
       
   340         typename Container::iterator jt;
       
   341         for (jt = container.begin(); jt != it; ++it) {
       
   342           (*it)->clear();
       
   343         }
       
   344         throw;
   321       }
   345       }
   322     }
   346     }
   323 
   347 
   324 
   348 
   325     /// \brief Notifies all the registered observers about all Items are 
   349     /// \brief Notifies all the registered observers about all Items are 
   333 	(*it)->clear();
   357 	(*it)->clear();
   334       }
   358       }
   335     }
   359     }
   336   };
   360   };
   337 
   361 
   338 
       
   339   /// \brief Class to extend a graph with the functionality of alteration
       
   340   /// observing.
       
   341   ///
       
   342   /// AlterableGraphExtender extends the _Base graphs functionality with
       
   343   /// the possibility of alteration observing. It defines two observer
       
   344   /// registrys for the nodes and mapes.
       
   345   /// 
       
   346   /// \todo Document what "alteration observing" is. And probably find a
       
   347   /// better (shorter) name.
       
   348   ///
       
   349   /// \param _Base is the base class to extend.
       
   350   ///
       
   351   /// \pre _Base is conform to the BaseGraphComponent concept.
       
   352   ///
       
   353   /// \post AlterableGraphExtender<_Base> is conform to the
       
   354   /// AlterableGraphComponent concept.
       
   355   ///
       
   356   /// \author Balazs Dezso
       
   357 
       
   358   template <typename _Base> 
       
   359   class AlterableGraphExtender : public _Base {
       
   360   public:
       
   361 
       
   362     typedef AlterableGraphExtender Graph;
       
   363     typedef _Base Parent;
       
   364 
       
   365     typedef typename Parent::Node Node;
       
   366     typedef typename Parent::Edge Edge;
       
   367 
       
   368     /// The edge observer registry.
       
   369     typedef AlterationNotifier<Edge> EdgeNotifier;
       
   370     /// The node observer registry.
       
   371     typedef AlterationNotifier<Node> NodeNotifier;
       
   372 
       
   373 
       
   374   protected:
       
   375 
       
   376     mutable EdgeNotifier edge_notifier;
       
   377 
       
   378     mutable NodeNotifier node_notifier;
       
   379 
       
   380   public:
       
   381 
       
   382     /// \brief Gives back the edge alteration notifier.
       
   383     ///
       
   384     /// Gives back the edge alteration notifier.
       
   385     EdgeNotifier& getNotifier(Edge) const {
       
   386       return edge_notifier;
       
   387     }
       
   388 
       
   389     /// \brief Gives back the node alteration notifier.
       
   390     ///
       
   391     /// Gives back the node alteration notifier.
       
   392     NodeNotifier& getNotifier(Node) const {
       
   393       return node_notifier;
       
   394     }
       
   395 
       
   396     ~AlterableGraphExtender() {
       
   397       node_notifier.clear();
       
   398       edge_notifier.clear();
       
   399     }
       
   400     
       
   401   };
       
   402 
       
   403 
       
   404   template <typename _Base> 
       
   405   class AlterableEdgeSetExtender : public _Base {
       
   406   public:
       
   407 
       
   408     typedef AlterableEdgeSetExtender Graph;
       
   409     typedef _Base Parent;
       
   410 
       
   411     typedef typename Parent::Edge Edge;
       
   412 
       
   413     /// The edge observer registry.
       
   414     typedef AlterationNotifier<Edge> EdgeNotifier;
       
   415 
       
   416   protected:
       
   417 
       
   418     mutable EdgeNotifier edge_notifier;
       
   419 
       
   420   public:
       
   421 
       
   422     /// \brief Gives back the edge alteration notifier.
       
   423     ///
       
   424     /// Gives back the edge alteration notifier.
       
   425     EdgeNotifier& getNotifier(Edge) const {
       
   426       return edge_notifier;
       
   427     }
       
   428 
       
   429     ~AlterableEdgeSetExtender() {
       
   430       edge_notifier.clear();
       
   431     }
       
   432     
       
   433   };
       
   434 
       
   435   /// \brief Class to extend an undirected graph with the functionality of
       
   436   /// alteration observing.
       
   437   ///
       
   438   /// \todo Document.
       
   439   ///
       
   440   /// \sa AlterableGraphExtender
       
   441   ///
       
   442   /// \bug This should be done some other way. Possibilities: template
       
   443   /// specialization (not very easy, if at all possible); some kind of
       
   444   /// enable_if boost technique?
       
   445 
       
   446   template <typename _Base> 
       
   447   class AlterableUGraphExtender
       
   448     : public AlterableGraphExtender<_Base> {
       
   449   public:
       
   450 
       
   451     typedef AlterableUGraphExtender Graph;
       
   452     typedef AlterableGraphExtender<_Base> Parent;
       
   453 
       
   454     typedef typename Parent::UEdge UEdge;
       
   455 
       
   456     /// The edge observer registry.
       
   457     typedef AlterationNotifier<UEdge> UEdgeNotifier;
       
   458 
       
   459   protected:
       
   460 
       
   461     mutable UEdgeNotifier u_edge_notifier;
       
   462 
       
   463   public:
       
   464 
       
   465     using Parent::getNotifier;
       
   466     UEdgeNotifier& getNotifier(UEdge) const {
       
   467       return u_edge_notifier;
       
   468     }
       
   469 
       
   470     ~AlterableUGraphExtender() {
       
   471       u_edge_notifier.clear();
       
   472     }
       
   473   };
       
   474 
       
   475   template <typename _Base> 
       
   476   class AlterableUEdgeSetExtender
       
   477     : public AlterableEdgeSetExtender<_Base> {
       
   478   public:
       
   479 
       
   480     typedef AlterableUEdgeSetExtender Graph;
       
   481     typedef AlterableEdgeSetExtender<_Base> Parent;
       
   482 
       
   483     typedef typename Parent::UEdge UEdge;
       
   484 
       
   485     typedef AlterationNotifier<UEdge> UEdgeNotifier;
       
   486 
       
   487   protected:
       
   488 
       
   489     mutable UEdgeNotifier u_edge_notifier;
       
   490 
       
   491   public:
       
   492 
       
   493     using Parent::getNotifier;
       
   494     UEdgeNotifier& getNotifier(UEdge) const {
       
   495       return u_edge_notifier;
       
   496     }
       
   497 
       
   498     ~AlterableUEdgeSetExtender() {
       
   499       u_edge_notifier.clear();
       
   500     }
       
   501   };
       
   502 
       
   503 
       
   504 
       
   505   template <typename _Base>
       
   506   class AlterableBpUGraphExtender : public _Base {
       
   507   public:
       
   508 
       
   509     typedef _Base Parent;
       
   510     typedef AlterableBpUGraphExtender Graph;
       
   511   
       
   512     typedef typename Parent::Node Node;
       
   513     typedef typename Parent::BNode BNode;
       
   514     typedef typename Parent::ANode ANode;
       
   515     typedef typename Parent::Edge Edge;
       
   516     typedef typename Parent::UEdge UEdge;
       
   517   
       
   518   
       
   519     typedef AlterationNotifier<Node> NodeNotifier;
       
   520     typedef AlterationNotifier<BNode> BNodeNotifier;
       
   521     typedef AlterationNotifier<ANode> ANodeNotifier;
       
   522     typedef AlterationNotifier<Edge> EdgeNotifier;
       
   523     typedef AlterationNotifier<UEdge> UEdgeNotifier;
       
   524 
       
   525   protected:
       
   526 
       
   527     mutable NodeNotifier nodeNotifier;
       
   528     mutable BNodeNotifier bNodeNotifier;
       
   529     mutable ANodeNotifier aNodeNotifier;
       
   530     mutable EdgeNotifier edgeNotifier;
       
   531     mutable UEdgeNotifier uEdgeNotifier;
       
   532 
       
   533   public:
       
   534 
       
   535     NodeNotifier& getNotifier(Node) const {
       
   536       return nodeNotifier;
       
   537     }
       
   538 
       
   539     BNodeNotifier& getNotifier(BNode) const {
       
   540       return bNodeNotifier;
       
   541     }
       
   542 
       
   543     ANodeNotifier& getNotifier(ANode) const {
       
   544       return aNodeNotifier;
       
   545     }
       
   546 
       
   547     EdgeNotifier& getNotifier(Edge) const {
       
   548       return edgeNotifier;
       
   549     }
       
   550 
       
   551     UEdgeNotifier& getNotifier(UEdge) const {
       
   552       return uEdgeNotifier;
       
   553     }
       
   554 
       
   555     ~AlterableBpUGraphExtender() {
       
   556       nodeNotifier.clear();
       
   557       bNodeNotifier.clear();
       
   558       aNodeNotifier.clear();
       
   559       edgeNotifier.clear();
       
   560       uEdgeNotifier.clear();
       
   561     }
       
   562 
       
   563   };
       
   564   
   362   
   565 /// @}
   363 /// @}
   566   
   364   
   567 
   365 
   568 }
   366 }