Keeping order of alteration observers
authordeba
Tue, 21 Nov 2006 17:28:08 +0000
changeset 23054a2236cc98a0
parent 2304 108d6db4f32a
child 2306 42cce226b87b
Keeping order of alteration observers

Removing some automatic callback generation
// exception safety reason
lemon/bits/alteration_notifier.h
lemon/matrix_maps.h
     1.1 --- a/lemon/bits/alteration_notifier.h	Mon Nov 20 10:14:21 2006 +0000
     1.2 +++ b/lemon/bits/alteration_notifier.h	Tue Nov 21 17:28:08 2006 +0000
     1.3 @@ -20,6 +20,7 @@
     1.4  #define LEMON_BITS_ALTERATION_NOTIFIER_H
     1.5  
     1.6  #include <vector>
     1.7 +#include <list>
     1.8  
     1.9  #include <lemon/bits/utility.h>
    1.10  
    1.11 @@ -173,8 +174,7 @@
    1.12        /// This member attaches the observer into an AlterationNotifier.
    1.13        ///
    1.14        void attach(AlterationNotifier& _notifier) {
    1.15 -	notifier = &_notifier;
    1.16 -	notifier->attach(*this);
    1.17 +	_notifier.attach(*this);
    1.18        }
    1.19        
    1.20        /// \brief Detaches the observer into an AlterationNotifier.
    1.21 @@ -203,7 +203,7 @@
    1.22      protected:
    1.23        
    1.24        Notifier* notifier;
    1.25 -      int notifier_index;
    1.26 +      typename std::list<ObserverBase*>::iterator index;
    1.27  
    1.28        /// \brief The member function to notificate the observer about an
    1.29        /// item is added to the container.
    1.30 @@ -211,7 +211,6 @@
    1.31        /// The add() member function notificates the observer about an item
    1.32        /// is added to the container. It have to be overrided in the
    1.33        /// subclasses.
    1.34 -	
    1.35        virtual void add(const Item&) = 0;
    1.36  
    1.37        /// \brief The member function to notificate the observer about 
    1.38 @@ -220,28 +219,14 @@
    1.39        /// The add() member function notificates the observer about more item
    1.40        /// is added to the container. It have to be overrided in the
    1.41        /// subclasses.
    1.42 -
    1.43 -      virtual void add(const std::vector<Item>& items) {
    1.44 -        int i;
    1.45 -        try {
    1.46 -          for (i = 0; i < (int)items.size(); ++i) {
    1.47 -            add(items[i]);
    1.48 -          }
    1.49 -        } catch (...) {
    1.50 -          for (int j = 0; j < i; ++j) {
    1.51 -            add(items[j]);
    1.52 -          }          
    1.53 -          throw;
    1.54 -        }
    1.55 -      }
    1.56 +      virtual void add(const std::vector<Item>& items) = 0;
    1.57  
    1.58        /// \brief The member function to notificate the observer about an
    1.59        /// item is erased from the container.
    1.60        ///
    1.61        /// The erase() member function notificates the observer about an
    1.62        /// item is erased from the container. It have to be overrided in
    1.63 -      /// the subclasses.
    1.64 -	
    1.65 +      /// the subclasses.	
    1.66        virtual void erase(const Item&) = 0;
    1.67  
    1.68        /// \brief The member function to notificate the observer about 
    1.69 @@ -250,11 +235,7 @@
    1.70        /// The erase() member function notificates the observer about more item
    1.71        /// is erased from the container. It have to be overrided in the
    1.72        /// subclasses.
    1.73 -      virtual void erase(const std::vector<Item>& items) {
    1.74 -        for (int i = 0; i < (int)items.size(); ++i) {
    1.75 -          erase(items[i]);
    1.76 -        }
    1.77 -      }
    1.78 +      virtual void erase(const std::vector<Item>& items) = 0;
    1.79  
    1.80        /// \brief The member function to notificate the observer about the
    1.81        /// container is built.
    1.82 @@ -263,20 +244,7 @@
    1.83        /// container is built from an empty container. It have to be
    1.84        /// overrided in the subclasses.
    1.85  
    1.86 -      virtual void build() {
    1.87 -        Item it;
    1.88 -        try {
    1.89 -          for (notifier->first(it); it != INVALID; notifier->next(it)) {
    1.90 -            add(it);
    1.91 -          }
    1.92 -        } catch (...) {
    1.93 -          Item jt;
    1.94 -          for (notifier->first(jt); jt != it; notifier->next(jt)) {
    1.95 -            erase(jt);
    1.96 -          }
    1.97 -          throw;
    1.98 -        }
    1.99 -      }
   1.100 +      virtual void build() = 0;
   1.101  
   1.102        /// \brief The member function to notificate the observer about all
   1.103        /// items are erased from the container.
   1.104 @@ -284,12 +252,7 @@
   1.105        /// The clear() member function notificates the observer about all
   1.106        /// items are erased from the container. It have to be overrided in
   1.107        /// the subclasses.      
   1.108 -      virtual void clear() {
   1.109 -        Item it;
   1.110 -        for (notifier->first(it); it != INVALID; notifier->next(it)) {
   1.111 -          erase(it);
   1.112 -        }
   1.113 -      }
   1.114 +      virtual void clear() = 0;
   1.115  
   1.116      };
   1.117  	
   1.118 @@ -297,7 +260,7 @@
   1.119  
   1.120      const Container* container;
   1.121  
   1.122 -    typedef std::vector<ObserverBase*> Observers; 
   1.123 +    typedef std::list<ObserverBase*> Observers; 
   1.124      Observers observers;
   1.125  
   1.126  		
   1.127 @@ -383,15 +346,13 @@
   1.128    protected:
   1.129  
   1.130      void attach(ObserverBase& observer) {
   1.131 -      observers.push_back(&observer);
   1.132 +      observer.index = observers.insert(observers.begin(), &observer);
   1.133        observer.notifier = this;
   1.134 -      observer.notifier_index = observers.size() - 1;
   1.135      } 
   1.136  
   1.137      void detach(ObserverBase& observer) {
   1.138 -      observers.back()->notifier_index = observer.notifier_index; 
   1.139 -      observers[observer.notifier_index] = observers.back();
   1.140 -      observers.pop_back();
   1.141 +      observers.erase(observer.index);
   1.142 +      observer.index = observers.end();
   1.143        observer.notifier = 0;
   1.144      }
   1.145  
   1.146 @@ -404,15 +365,15 @@
   1.147      /// the container.
   1.148      /// 
   1.149      void add(const Item& item) {
   1.150 -      typename Observers::iterator it;
   1.151 +      typename Observers::reverse_iterator it;
   1.152        try {
   1.153 -        for (it = observers.begin(); it != observers.end(); ++it) {
   1.154 +        for (it = observers.rbegin(); it != observers.rend(); ++it) {
   1.155            (*it)->add(item);
   1.156          }
   1.157        } catch (...) {
   1.158          typename Observers::iterator jt;
   1.159 -        for (jt = observers.begin(); jt != it; ++jt) {
   1.160 -          (*it)->erase(item);
   1.161 +        for (jt = it.base(); jt != observers.end(); ++jt) {
   1.162 +          (*jt)->erase(item);
   1.163          }
   1.164          throw;
   1.165        }
   1.166 @@ -425,15 +386,15 @@
   1.167      /// the container.
   1.168      /// 
   1.169      void add(const std::vector<Item>& items) {
   1.170 -      typename Observers::iterator it;
   1.171 +      typename Observers::reverse_iterator it;
   1.172        try {
   1.173 -        for (it = observers.begin(); it != observers.end(); ++it) {
   1.174 +        for (it = observers.rbegin(); it != observers.rend(); ++it) {
   1.175            (*it)->add(items);
   1.176          }
   1.177        } catch (...) {
   1.178          typename Observers::iterator jt;
   1.179 -        for (jt = observers.begin(); jt != it; ++jt) {
   1.180 -          (*it)->erase(items);
   1.181 +        for (jt = it.base(); jt != observers.end(); ++jt) {
   1.182 +          (*jt)->erase(items);
   1.183          }
   1.184          throw;
   1.185        }
   1.186 @@ -445,14 +406,16 @@
   1.187      /// It notifies all the registed observers about an item erased from 
   1.188      /// the container.
   1.189      /// 
   1.190 -    void erase(const Item& key) throw() {
   1.191 -      int i = 0;
   1.192 -      while (i != (int)observers.size()) {
   1.193 +    void erase(const Item& item) throw() {
   1.194 +      typename Observers::iterator it = observers.begin();
   1.195 +      while (it != observers.end()) {
   1.196          try {
   1.197 -          observers[i]->erase(key);
   1.198 -          ++i;
   1.199 +          (*it)->erase(item);
   1.200 +          ++it;
   1.201          } catch (const ImmediateDetach&) {
   1.202 -          observers[i]->detach();
   1.203 +          it = observers.erase(it);
   1.204 +          (*it)->index = observers.end();
   1.205 +          (*it)->notifier = 0;
   1.206          }
   1.207        }
   1.208      }
   1.209 @@ -464,13 +427,15 @@
   1.210      /// the container.
   1.211      /// 
   1.212      void erase(const std::vector<Item>& items) {
   1.213 -      int i = 0;
   1.214 -      while (i != (int)observers.size()) {
   1.215 +      typename Observers::iterator it = observers.begin();
   1.216 +      while (it != observers.end()) {
   1.217          try {
   1.218 -          observers[i]->erase(items);
   1.219 -          ++i;
   1.220 +          (*it)->erase(items);
   1.221 +          ++it;
   1.222          } catch (const ImmediateDetach&) {
   1.223 -          observers[i]->detach();
   1.224 +          it = observers.erase(it);
   1.225 +          (*it)->index = observers.end();
   1.226 +          (*it)->notifier = 0;
   1.227          }
   1.228        }
   1.229      }
   1.230 @@ -481,15 +446,15 @@
   1.231      /// Notifies all the registed observers about the container is built
   1.232      /// from an empty container.
   1.233      void build() {
   1.234 -      typename Observers::iterator it;
   1.235 +      typename Observers::reverse_iterator it;
   1.236        try {
   1.237 -        for (it = observers.begin(); it != observers.end(); ++it) {
   1.238 +        for (it = observers.rbegin(); it != observers.rend(); ++it) {
   1.239            (*it)->build();
   1.240          }
   1.241        } catch (...) {
   1.242          typename Observers::iterator jt;
   1.243 -        for (jt = observers.begin(); jt != it; ++jt) {
   1.244 -          (*it)->clear();
   1.245 +        for (jt = it.base(); jt != observers.end(); ++jt) {
   1.246 +          (*jt)->clear();
   1.247          }
   1.248          throw;
   1.249        }
   1.250 @@ -501,13 +466,15 @@
   1.251      /// Notifies all the registed observers about all items are erased
   1.252      /// from the container.
   1.253      void clear() {
   1.254 -      int i = 0;
   1.255 -      while (i != (int)observers.size()) {
   1.256 +      typename Observers::iterator it = observers.begin();
   1.257 +      while (it != observers.end()) {
   1.258          try {
   1.259 -          observers[i]->clear();
   1.260 -          ++i;
   1.261 +          (*it)->clear();
   1.262 +          ++it;
   1.263          } catch (const ImmediateDetach&) {
   1.264 -          observers[i]->detach();
   1.265 +          it = observers.erase(it);
   1.266 +          (*it)->index = observers.end();
   1.267 +          (*it)->notifier = 0;
   1.268          }
   1.269        }
   1.270      }
     2.1 --- a/lemon/matrix_maps.h	Mon Nov 20 10:14:21 2006 +0000
     2.2 +++ b/lemon/matrix_maps.h	Tue Nov 21 17:28:08 2006 +0000
     2.3 @@ -354,8 +354,22 @@
     2.4        }
     2.5      }
     2.6  
     2.7 +    virtual void add(const std::vector<Key>& keys) {
     2.8 +      int new_size = 0;
     2.9 +      for (int i = 0; i < (int)keys.size(); ++i) {
    2.10 +        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
    2.11 +          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);	
    2.12 +        }
    2.13 +      }
    2.14 +      if (new_size > (int)values.size()) {
    2.15 +        values.resize(new_size);
    2.16 +      }
    2.17 +    }
    2.18 +
    2.19      virtual void erase(const Key&) {}
    2.20  
    2.21 +    virtual void erase(const std::vector<Key>&) {}
    2.22 +
    2.23      virtual void build() {
    2.24        values.resize(size(Parent::getNotifier()->maxId() + 1));
    2.25      }
    2.26 @@ -495,8 +509,22 @@
    2.27        }
    2.28      }
    2.29  
    2.30 +    virtual void add(const std::vector<Key>& keys) {
    2.31 +      int new_size = 0;
    2.32 +      for (int i = 0; i < (int)keys.size(); ++i) {
    2.33 +        if (size(Parent::getNotifier()->id(keys[i]) + 1) >= new_size) {
    2.34 +          new_size = size(Parent::getNotifier()->id(keys[i]) + 1);	
    2.35 +        }
    2.36 +      }
    2.37 +      if (new_size > (int)values.size()) {
    2.38 +        values.resize(new_size);
    2.39 +      }
    2.40 +    }
    2.41 +
    2.42      virtual void erase(const Key&) {}
    2.43  
    2.44 +    virtual void erase(const std::vector<Key>&) {}
    2.45 +
    2.46      virtual void build() {
    2.47        values.resize(size(Parent::getNotifier()->maxId() + 1));
    2.48      }