COIN-OR::LEMON - Graph Library

Changeset 2305:4a2236cc98a0 in lemon-0.x for lemon/bits


Ignore:
Timestamp:
11/21/06 18:28:08 (13 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3080
Message:

Keeping order of alteration observers

Removing some automatic callback generation
exception safety reason

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/bits/alteration_notifier.h

    r2188 r2305  
    2121
    2222#include <vector>
     23#include <list>
    2324
    2425#include <lemon/bits/utility.h>
     
    174175      ///
    175176      void attach(AlterationNotifier& _notifier) {
    176         notifier = &_notifier;
    177         notifier->attach(*this);
     177        _notifier.attach(*this);
    178178      }
    179179     
     
    204204     
    205205      Notifier* notifier;
    206       int notifier_index;
     206      typename std::list<ObserverBase*>::iterator index;
    207207
    208208      /// \brief The member function to notificate the observer about an
     
    212212      /// is added to the container. It have to be overrided in the
    213213      /// subclasses.
    214        
    215214      virtual void add(const Item&) = 0;
    216215
     
    221220      /// is added to the container. It have to be overrided in the
    222221      /// subclasses.
    223 
    224       virtual void add(const std::vector<Item>& items) {
    225         int i;
    226         try {
    227           for (i = 0; i < (int)items.size(); ++i) {
    228             add(items[i]);
    229           }
    230         } catch (...) {
    231           for (int j = 0; j < i; ++j) {
    232             add(items[j]);
    233           }         
    234           throw;
    235         }
    236       }
     222      virtual void add(const std::vector<Item>& items) = 0;
    237223
    238224      /// \brief The member function to notificate the observer about an
     
    241227      /// The erase() member function notificates the observer about an
    242228      /// item is erased from the container. It have to be overrided in
    243       /// the subclasses.
    244        
     229      /// the subclasses.       
    245230      virtual void erase(const Item&) = 0;
    246231
     
    251236      /// is erased from the container. It have to be overrided in the
    252237      /// subclasses.
    253       virtual void erase(const std::vector<Item>& items) {
    254         for (int i = 0; i < (int)items.size(); ++i) {
    255           erase(items[i]);
    256         }
    257       }
     238      virtual void erase(const std::vector<Item>& items) = 0;
    258239
    259240      /// \brief The member function to notificate the observer about the
     
    264245      /// overrided in the subclasses.
    265246
    266       virtual void build() {
    267         Item it;
    268         try {
    269           for (notifier->first(it); it != INVALID; notifier->next(it)) {
    270             add(it);
    271           }
    272         } catch (...) {
    273           Item jt;
    274           for (notifier->first(jt); jt != it; notifier->next(jt)) {
    275             erase(jt);
    276           }
    277           throw;
    278         }
    279       }
     247      virtual void build() = 0;
    280248
    281249      /// \brief The member function to notificate the observer about all
     
    285253      /// items are erased from the container. It have to be overrided in
    286254      /// the subclasses.     
    287       virtual void clear() {
    288         Item it;
    289         for (notifier->first(it); it != INVALID; notifier->next(it)) {
    290           erase(it);
    291         }
    292       }
     255      virtual void clear() = 0;
    293256
    294257    };
     
    298261    const Container* container;
    299262
    300     typedef std::vector<ObserverBase*> Observers;
     263    typedef std::list<ObserverBase*> Observers;
    301264    Observers observers;
    302265
     
    384347
    385348    void attach(ObserverBase& observer) {
    386       observers.push_back(&observer);
     349      observer.index = observers.insert(observers.begin(), &observer);
    387350      observer.notifier = this;
    388       observer.notifier_index = observers.size() - 1;
    389351    }
    390352
    391353    void detach(ObserverBase& observer) {
    392       observers.back()->notifier_index = observer.notifier_index;
    393       observers[observer.notifier_index] = observers.back();
    394       observers.pop_back();
     354      observers.erase(observer.index);
     355      observer.index = observers.end();
    395356      observer.notifier = 0;
    396357    }
     
    405366    ///
    406367    void add(const Item& item) {
    407       typename Observers::iterator it;
     368      typename Observers::reverse_iterator it;
    408369      try {
    409         for (it = observers.begin(); it != observers.end(); ++it) {
     370        for (it = observers.rbegin(); it != observers.rend(); ++it) {
    410371          (*it)->add(item);
    411372        }
    412373      } catch (...) {
    413374        typename Observers::iterator jt;
    414         for (jt = observers.begin(); jt != it; ++jt) {
    415           (*it)->erase(item);
     375        for (jt = it.base(); jt != observers.end(); ++jt) {
     376          (*jt)->erase(item);
    416377        }
    417378        throw;
     
    426387    ///
    427388    void add(const std::vector<Item>& items) {
    428       typename Observers::iterator it;
     389      typename Observers::reverse_iterator it;
    429390      try {
    430         for (it = observers.begin(); it != observers.end(); ++it) {
     391        for (it = observers.rbegin(); it != observers.rend(); ++it) {
    431392          (*it)->add(items);
    432393        }
    433394      } catch (...) {
    434395        typename Observers::iterator jt;
    435         for (jt = observers.begin(); jt != it; ++jt) {
    436           (*it)->erase(items);
     396        for (jt = it.base(); jt != observers.end(); ++jt) {
     397          (*jt)->erase(items);
    437398        }
    438399        throw;
     
    446407    /// the container.
    447408    ///
    448     void erase(const Item& key) throw() {
    449       int i = 0;
    450       while (i != (int)observers.size()) {
     409    void erase(const Item& item) throw() {
     410      typename Observers::iterator it = observers.begin();
     411      while (it != observers.end()) {
    451412        try {
    452           observers[i]->erase(key);
    453           ++i;
     413          (*it)->erase(item);
     414          ++it;
    454415        } catch (const ImmediateDetach&) {
    455           observers[i]->detach();
     416          it = observers.erase(it);
     417          (*it)->index = observers.end();
     418          (*it)->notifier = 0;
    456419        }
    457420      }
     
    465428    ///
    466429    void erase(const std::vector<Item>& items) {
    467       int i = 0;
    468       while (i != (int)observers.size()) {
     430      typename Observers::iterator it = observers.begin();
     431      while (it != observers.end()) {
    469432        try {
    470           observers[i]->erase(items);
    471           ++i;
     433          (*it)->erase(items);
     434          ++it;
    472435        } catch (const ImmediateDetach&) {
    473           observers[i]->detach();
     436          it = observers.erase(it);
     437          (*it)->index = observers.end();
     438          (*it)->notifier = 0;
    474439        }
    475440      }
     
    482447    /// from an empty container.
    483448    void build() {
    484       typename Observers::iterator it;
     449      typename Observers::reverse_iterator it;
    485450      try {
    486         for (it = observers.begin(); it != observers.end(); ++it) {
     451        for (it = observers.rbegin(); it != observers.rend(); ++it) {
    487452          (*it)->build();
    488453        }
    489454      } catch (...) {
    490455        typename Observers::iterator jt;
    491         for (jt = observers.begin(); jt != it; ++jt) {
    492           (*it)->clear();
     456        for (jt = it.base(); jt != observers.end(); ++jt) {
     457          (*jt)->clear();
    493458        }
    494459        throw;
     
    502467    /// from the container.
    503468    void clear() {
    504       int i = 0;
    505       while (i != (int)observers.size()) {
     469      typename Observers::iterator it = observers.begin();
     470      while (it != observers.end()) {
    506471        try {
    507           observers[i]->clear();
    508           ++i;
     472          (*it)->clear();
     473          ++it;
    509474        } catch (const ImmediateDetach&) {
    510           observers[i]->detach();
     475          it = observers.erase(it);
     476          (*it)->index = observers.end();
     477          (*it)->notifier = 0;
    511478        }
    512479      }
Note: See TracChangeset for help on using the changeset viewer.