COIN-OR::LEMON - Graph Library

Changeset 2188:984870a2dde4 in lemon-0.x


Ignore:
Timestamp:
09/04/06 13:05:21 (13 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@2913
Message:

Improvment in exception handling
The erase and clear handlers have to be exception safe.
These can throw only one exception which detach the observer
from the notifier

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/bits/alteration_notifier.h

    r2006 r2188  
    6767  /// The alteration can be observed with a class inherited from the
    6868  /// \e ObserverBase nested class. The signals can be handled with
    69   /// overriding the virtual functions defined in the base class.
    70   /// The observer base can be attached to the notifier with the
    71   /// \e attach() member and can be detached with detach() function.
    72   ///
    73   /// Alteration observers try to be exception safe. This can be achived
    74   /// when the observers does not throw exception on \e erase() and
    75   /// \e clear(). Less strict condition is that the \e erase() should
    76   /// not throw exception after an \e add() with the same parameter and
    77   /// the \e clear() should not throw exception after a \e build().
     69  /// overriding the virtual functions defined in the base class.  The
     70  /// observer base can be attached to the notifier with the
     71  /// \e attach() member and can be detached with detach() function. The
     72  /// alteration handlers should not call any function which signals
     73  /// an other alteration in the same notifier and should not
     74  /// detach any observer from the notifier.
     75  ///
     76  /// Alteration observers try to be exception safe. If an \e add() or
     77  /// a \e clear() function throws an exception then the remaining
     78  /// observeres will not be notified and the fulfilled additions will
     79  /// be rolled back by calling the \e erase() or \e clear()
     80  /// functions. Thence the \e erase() and \e clear() should not throw
     81  /// exception. Actullay, it can be throw only
     82  /// \ref AlterationObserver::ImmediateDetach ImmediateDetach
     83  /// exception which detach the observer from the notifier.
    7884  ///
    7985  /// There are some place when the alteration observing is not completly
     
    100106    typedef _Item Item;
    101107
     108    /// \brief Exception which can be called from \e clear() and
     109    /// \e erase().
     110    ///
     111    /// From the \e clear() and \e erase() function only this
     112    /// exception is allowed to throw. The exception immediatly
     113    /// detaches the current observer from the notifier. Because the
     114    /// \e clear() and \e erase() should not throw other exceptions
     115    /// it can be used to invalidate the observer.
     116    struct ImmediateDetach {};
     117
    102118    /// \brief ObserverBase is the base class for the observers.
    103119    ///
     
    161177        notifier->attach(*this);
    162178      }
    163 
     179     
    164180      /// \brief Detaches the observer into an AlterationNotifier.
    165181      ///
     
    169185        notifier->detach(*this);
    170186      }
    171        
    172 
     187     
    173188      /// \brief Gives back a pointer to the notifier which the map
    174189      /// attached into.
     
    431446    /// the container.
    432447    ///
    433     void erase(const Item& key) {
    434       typename Observers::iterator it;
    435       for (it = observers.begin(); it != observers.end(); ++it) {
    436         (*it)->erase(key);
     448    void erase(const Item& key) throw() {
     449      int i = 0;
     450      while (i != (int)observers.size()) {
     451        try {
     452          observers[i]->erase(key);
     453          ++i;
     454        } catch (const ImmediateDetach&) {
     455          observers[i]->detach();
     456        }
    437457      }
    438458    }
     
    445465    ///
    446466    void erase(const std::vector<Item>& items) {
    447       typename Observers::iterator it;
    448       for (it = observers.begin(); it != observers.end(); ++it) {
    449         (*it)->erase(items);
     467      int i = 0;
     468      while (i != (int)observers.size()) {
     469        try {
     470          observers[i]->erase(items);
     471          ++i;
     472        } catch (const ImmediateDetach&) {
     473          observers[i]->detach();
     474        }
    450475      }
    451476    }
     
    471496    }
    472497
    473 
    474498    /// \brief Notifies all the registed observers about all items are
    475499    /// erased.
     
    478502    /// from the container.
    479503    void clear() {
    480       typename Observers::iterator it;
    481       for (it = observers.begin(); it != observers.end(); ++it) {
    482         (*it)->clear();
     504      int i = 0;
     505      while (i != (int)observers.size()) {
     506        try {
     507          observers[i]->clear();
     508          ++i;
     509        } catch (const ImmediateDetach&) {
     510          observers[i]->detach();
     511        }
    483512      }
    484513    }
Note: See TracChangeset for help on using the changeset viewer.