[Lemon-commits] deba: r3080 - in hugo/trunk/lemon: . bits

Lemon SVN svn at lemon.cs.elte.hu
Tue Nov 21 18:28:08 CET 2006


Author: deba
Date: Tue Nov 21 18:28:08 2006
New Revision: 3080

Modified:
   hugo/trunk/lemon/bits/alteration_notifier.h
   hugo/trunk/lemon/matrix_maps.h

Log:
Keeping order of alteration observers

Removing some automatic callback generation 
// exception safety reason




Modified: hugo/trunk/lemon/bits/alteration_notifier.h
==============================================================================
--- hugo/trunk/lemon/bits/alteration_notifier.h	(original)
+++ hugo/trunk/lemon/bits/alteration_notifier.h	Tue Nov 21 18:28:08 2006
@@ -20,6 +20,7 @@
 #define LEMON_BITS_ALTERATION_NOTIFIER_H
 
 #include <vector>
+#include <list>
 
 #include <lemon/bits/utility.h>
 
@@ -173,8 +174,7 @@
       /// This member attaches the observer into an AlterationNotifier.
       ///
       void attach(AlterationNotifier& _notifier) {
-	notifier = &_notifier;
-	notifier->attach(*this);
+	_notifier.attach(*this);
       }
       
       /// \brief Detaches the observer into an AlterationNotifier.
@@ -203,7 +203,7 @@
     protected:
       
       Notifier* notifier;
-      int notifier_index;
+      typename std::list<ObserverBase*>::iterator index;
 
       /// \brief The member function to notificate the observer about an
       /// item is added to the container.
@@ -211,7 +211,6 @@
       /// The add() member function notificates the observer about an item
       /// is added to the container. It have to be overrided in the
       /// subclasses.
-	
       virtual void add(const Item&) = 0;
 
       /// \brief The member function to notificate the observer about 
@@ -220,28 +219,14 @@
       /// The add() member function notificates the observer about more item
       /// is added to the container. It have to be overrided in the
       /// subclasses.
-
-      virtual void add(const std::vector<Item>& items) {
-        int i;
-        try {
-          for (i = 0; i < (int)items.size(); ++i) {
-            add(items[i]);
-          }
-        } catch (...) {
-          for (int j = 0; j < i; ++j) {
-            add(items[j]);
-          }          
-          throw;
-        }
-      }
+      virtual void add(const std::vector<Item>& items) = 0;
 
       /// \brief The member function to notificate the observer about an
       /// item is erased from the container.
       ///
       /// The erase() member function notificates the observer about an
       /// item is erased from the container. It have to be overrided in
-      /// the subclasses.
-	
+      /// the subclasses.	
       virtual void erase(const Item&) = 0;
 
       /// \brief The member function to notificate the observer about 
@@ -250,11 +235,7 @@
       /// The erase() member function notificates the observer about more item
       /// is erased from the container. It have to be overrided in the
       /// subclasses.
-      virtual void erase(const std::vector<Item>& items) {
-        for (int i = 0; i < (int)items.size(); ++i) {
-          erase(items[i]);
-        }
-      }
+      virtual void erase(const std::vector<Item>& items) = 0;
 
       /// \brief The member function to notificate the observer about the
       /// container is built.
@@ -263,20 +244,7 @@
       /// container is built from an empty container. It have to be
       /// overrided in the subclasses.
 
-      virtual void build() {
-        Item it;
-        try {
-          for (notifier->first(it); it != INVALID; notifier->next(it)) {
-            add(it);
-          }
-        } catch (...) {
-          Item jt;
-          for (notifier->first(jt); jt != it; notifier->next(jt)) {
-            erase(jt);
-          }
-          throw;
-        }
-      }
+      virtual void build() = 0;
 
       /// \brief The member function to notificate the observer about all
       /// items are erased from the container.
@@ -284,12 +252,7 @@
       /// The clear() member function notificates the observer about all
       /// items are erased from the container. It have to be overrided in
       /// the subclasses.      
-      virtual void clear() {
-        Item it;
-        for (notifier->first(it); it != INVALID; notifier->next(it)) {
-          erase(it);
-        }
-      }
+      virtual void clear() = 0;
 
     };
 	
@@ -297,7 +260,7 @@
 
     const Container* container;
 
-    typedef std::vector<ObserverBase*> Observers; 
+    typedef std::list<ObserverBase*> Observers; 
     Observers observers;
 
 		
@@ -383,15 +346,13 @@
   protected:
 
     void attach(ObserverBase& observer) {
-      observers.push_back(&observer);
+      observer.index = observers.insert(observers.begin(), &observer);
       observer.notifier = this;
-      observer.notifier_index = observers.size() - 1;
     } 
 
     void detach(ObserverBase& observer) {
-      observers.back()->notifier_index = observer.notifier_index; 
-      observers[observer.notifier_index] = observers.back();
-      observers.pop_back();
+      observers.erase(observer.index);
+      observer.index = observers.end();
       observer.notifier = 0;
     }
 
@@ -404,15 +365,15 @@
     /// the container.
     /// 
     void add(const Item& item) {
-      typename Observers::iterator it;
+      typename Observers::reverse_iterator it;
       try {
-        for (it = observers.begin(); it != observers.end(); ++it) {
+        for (it = observers.rbegin(); it != observers.rend(); ++it) {
           (*it)->add(item);
         }
       } catch (...) {
         typename Observers::iterator jt;
-        for (jt = observers.begin(); jt != it; ++jt) {
-          (*it)->erase(item);
+        for (jt = it.base(); jt != observers.end(); ++jt) {
+          (*jt)->erase(item);
         }
         throw;
       }
@@ -425,15 +386,15 @@
     /// the container.
     /// 
     void add(const std::vector<Item>& items) {
-      typename Observers::iterator it;
+      typename Observers::reverse_iterator it;
       try {
-        for (it = observers.begin(); it != observers.end(); ++it) {
+        for (it = observers.rbegin(); it != observers.rend(); ++it) {
           (*it)->add(items);
         }
       } catch (...) {
         typename Observers::iterator jt;
-        for (jt = observers.begin(); jt != it; ++jt) {
-          (*it)->erase(items);
+        for (jt = it.base(); jt != observers.end(); ++jt) {
+          (*jt)->erase(items);
         }
         throw;
       }
@@ -445,14 +406,16 @@
     /// It notifies all the registed observers about an item erased from 
     /// the container.
     /// 
-    void erase(const Item& key) throw() {
-      int i = 0;
-      while (i != (int)observers.size()) {
+    void erase(const Item& item) throw() {
+      typename Observers::iterator it = observers.begin();
+      while (it != observers.end()) {
         try {
-          observers[i]->erase(key);
-          ++i;
+          (*it)->erase(item);
+          ++it;
         } catch (const ImmediateDetach&) {
-          observers[i]->detach();
+          it = observers.erase(it);
+          (*it)->index = observers.end();
+          (*it)->notifier = 0;
         }
       }
     }
@@ -464,13 +427,15 @@
     /// the container.
     /// 
     void erase(const std::vector<Item>& items) {
-      int i = 0;
-      while (i != (int)observers.size()) {
+      typename Observers::iterator it = observers.begin();
+      while (it != observers.end()) {
         try {
-          observers[i]->erase(items);
-          ++i;
+          (*it)->erase(items);
+          ++it;
         } catch (const ImmediateDetach&) {
-          observers[i]->detach();
+          it = observers.erase(it);
+          (*it)->index = observers.end();
+          (*it)->notifier = 0;
         }
       }
     }
@@ -481,15 +446,15 @@
     /// Notifies all the registed observers about the container is built
     /// from an empty container.
     void build() {
-      typename Observers::iterator it;
+      typename Observers::reverse_iterator it;
       try {
-        for (it = observers.begin(); it != observers.end(); ++it) {
+        for (it = observers.rbegin(); it != observers.rend(); ++it) {
           (*it)->build();
         }
       } catch (...) {
         typename Observers::iterator jt;
-        for (jt = observers.begin(); jt != it; ++jt) {
-          (*it)->clear();
+        for (jt = it.base(); jt != observers.end(); ++jt) {
+          (*jt)->clear();
         }
         throw;
       }
@@ -501,13 +466,15 @@
     /// Notifies all the registed observers about all items are erased
     /// from the container.
     void clear() {
-      int i = 0;
-      while (i != (int)observers.size()) {
+      typename Observers::iterator it = observers.begin();
+      while (it != observers.end()) {
         try {
-          observers[i]->clear();
-          ++i;
+          (*it)->clear();
+          ++it;
         } catch (const ImmediateDetach&) {
-          observers[i]->detach();
+          it = observers.erase(it);
+          (*it)->index = observers.end();
+          (*it)->notifier = 0;
         }
       }
     }

Modified: hugo/trunk/lemon/matrix_maps.h
==============================================================================
--- hugo/trunk/lemon/matrix_maps.h	(original)
+++ hugo/trunk/lemon/matrix_maps.h	Tue Nov 21 18:28:08 2006
@@ -354,8 +354,22 @@
       }
     }
 
+    virtual void add(const std::vector<Key>& keys) {
+      int new_size = 0;
+      for (int i = 0; i < (int)keys.size(); ++i) {
+        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
+          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);	
+        }
+      }
+      if (new_size > (int)values.size()) {
+        values.resize(new_size);
+      }
+    }
+
     virtual void erase(const Key&) {}
 
+    virtual void erase(const std::vector<Key>&) {}
+
     virtual void build() {
       values.resize(size(Parent::getNotifier()->maxId() + 1));
     }
@@ -495,8 +509,22 @@
       }
     }
 
+    virtual void add(const std::vector<Key>& keys) {
+      int new_size = 0;
+      for (int i = 0; i < (int)keys.size(); ++i) {
+        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
+          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);	
+        }
+      }
+      if (new_size > (int)values.size()) {
+        values.resize(new_size);
+      }
+    }
+
     virtual void erase(const Key&) {}
 
+    virtual void erase(const std::vector<Key>&) {}
+
     virtual void build() {
       values.resize(size(Parent::getNotifier()->maxId() + 1));
     }



More information about the Lemon-commits mailing list