COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/alteration_notifier.h @ 1996:5dc13b93f8b4

Last change on this file since 1996:5dc13b93f8b4 was 1996:5dc13b93f8b4, checked in by Balazs Dezso, 18 years ago

Some documentation arrangement modification

File size: 10.4 KB
RevLine 
[946]1/* -*- C++ -*-
2 *
[1956]3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
[946]8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
[1989]19#ifndef LEMON_ALTERATION_NOTIFIER_H
20#define LEMON_ALTERATION_NOTIFIER_H
[946]21
22#include <vector>
23#include <algorithm>
24
[1996]25///\ingroup graphbits
[946]26///\file
27///\brief Observer registry for graph alteration observers.
28
29namespace lemon {
30
[1996]31  /// \addtogroup graphbits
[946]32  /// @{
33
[1414]34  /// \brief Registry class to register objects observes alterations in
35  /// the graph.
36  ///
[946]37  /// This class is a registry for the objects which observe the
38  /// alterations in a container. The alteration observers can be attached
39  /// to and detached from the registry. The observers have to inherit
[1038]40  /// from the \ref AlterationNotifier::ObserverBase and override
[946]41  /// the virtual functions in that.
42  ///
43  /// The most important application of the alteration observing is the
[1414]44  /// dynamic map implementation.
[946]45  ///
46  /// \param _Item The item type what the observers are observing, usually
47  /// edge or node.
48  ///
49  /// \author Balazs Dezso
50
51  template <typename _Item>
[1038]52  class AlterationNotifier {
[946]53  public:
[1989]54
55    typedef True Notifier;
56
[946]57    typedef _Item Item;
58
59    /// ObserverBase is the base class for the observers.
60       
61    /// ObserverBase is the abstract base class for the observers.
62    /// It will be notified about an item was inserted into or
63    /// erased from the graph.
64    ///
65    /// The observer interface contains some pure virtual functions
66    /// to override. The add() and erase() functions are
67    /// to notify the oberver when one item is added or
68    /// erased.
69    ///
70    /// The build() and clear() members are to notify the observer
[1204]71    /// about the container is built from an empty container or
[946]72    /// is cleared to an empty container.
73    ///
74    /// \author Balazs Dezso
75
76    class ObserverBase {
77    protected:
[1038]78      typedef AlterationNotifier Registry;
[946]79
[1038]80      friend class AlterationNotifier;
[946]81
[1414]82      /// \brief Default constructor.
83      ///
[946]84      /// Default constructor for ObserverBase.
85      ///
86      ObserverBase() : registry(0) {}
87
[1685]88      ObserverBase(const ObserverBase& copy) {
89        if (copy.attached()) {
90          copy.getRegistry()->attach(*this);
91        }
92      }
93       
[946]94      virtual ~ObserverBase() {}
95
[1414]96      /// \brief Attaches the observer into an AlterationNotifier.
97      ///
[1038]98      /// This member attaches the observer into an AlterationNotifier.
[946]99      ///
[1038]100      void attach(AlterationNotifier& r) {
[946]101        registry = &r;
102        registry->attach(*this);
103      }
104
[1414]105      /// \brief Detaches the observer into an AlterationNotifier.
106      ///
[1038]107      /// This member detaches the observer from an AlterationNotifier.
[946]108      ///
109      void detach() {
110        if (registry) {
111          registry->detach(*this);
112        }
113      }
114       
115
116      /// Gives back a pointer to the registry what the map attached into.
117
118      /// This function gives back a pointer to the registry what the map
119      /// attached into.
120      ///
121      Registry* getRegistry() const { return const_cast<Registry*>(registry); }
122     
123      /// Gives back true when the observer is attached into a registry.
124      bool attached() const { return registry != 0; }
[1685]125
[946]126    private:
127
128      ObserverBase& operator=(const ObserverBase& copy);
129
130    protected:
131     
132      Registry* registry;
133      int registry_index;
134
135      /// \brief The member function to notificate the observer about an
136      /// item is added to the container.
137      ///
138      /// The add() member function notificates the observer about an item
139      /// is added to the container. It have to be overrided in the
140      /// subclasses.
141       
[1414]142      virtual void add(const Item&) = 0;
[946]143
[1414]144      /// \brief The member function to notificate the observer about
[1718]145      /// more item is added to the container.
[1414]146      ///
[1718]147      /// The add() member function notificates the observer about more item
[1414]148      /// is added to the container. It have to be overrided in the
149      /// subclasses.
150
151      virtual void add(const std::vector<Item>& items) {
152        for (int i = 0; i < (int)items.size(); ++i) {
153          add(items[i]);
154        }
155      }
[946]156
157      /// \brief The member function to notificate the observer about an
158      /// item is erased from the container.
159      ///
160      /// The erase() member function notificates the observer about an
161      /// item is erased from the container. It have to be overrided in
162      /// the subclasses.
163       
164      virtual void erase(const Item&) = 0;
165
[1718]166      /// \brief The member function to notificate the observer about
167      /// more item is erased from the container.
168      ///
169      /// The erase() member function notificates the observer about more item
170      /// is erased from the container. It have to be overrided in the
171      /// subclasses.
[1414]172      virtual void erase(const std::vector<Item>& items) {
173        for (int i = 0; i < (int)items.size(); ++i) {
[1701]174          erase(items[i]);
[1414]175        }
176      }
177
[946]178      /// \brief The member function to notificate the observer about the
[1204]179      /// container is built.
[946]180      ///
181      /// The build() member function notificates the observer about the
[1204]182      /// container is built from an empty container. It have to be
[946]183      /// overrided in the subclasses.
184
185      virtual void build() = 0;
186
187      /// \brief The member function to notificate the observer about all
188      /// items are erased from the container.
189      ///
190      /// The clear() member function notificates the observer about all
191      /// items are erased from the container. It have to be overrided in
192      /// the subclasses.
193     
194      virtual void clear() = 0;
195
196    };
197       
198  protected:
199       
200
201    typedef std::vector<ObserverBase*> Container;
202
203    Container container;
204
205               
206  public:
207
208    /// Default constructor.
209       
210    ///
[1038]211    /// The default constructor of the AlterationNotifier.
[946]212    /// It creates an empty registry.
[1038]213    AlterationNotifier() {}
[946]214
[1038]215    /// Copy Constructor of the AlterationNotifier.
[946]216       
[1038]217    /// Copy constructor of the AlterationNotifier.
[946]218    /// It creates only an empty registry because the copiable
219    /// registry's observers have to be registered still into that registry.
[1039]220    AlterationNotifier(const AlterationNotifier&) {}
[946]221
222    /// Assign operator.
223               
[1038]224    /// Assign operator for the AlterationNotifier.
[1040]225    /// It makes the notifier only empty because the copiable
226    /// notifier's observers have to be registered still into that registry.
[1039]227    AlterationNotifier& operator=(const AlterationNotifier&) {
[946]228      typename Container::iterator it;
229      for (it = container.begin(); it != container.end(); ++it) {
230        (*it)->registry = 0;
231      }
232    }
233
234    /// Destructor.
235                               
[1038]236    /// Destructor of the AlterationNotifier.
[946]237    ///
[1038]238    ~AlterationNotifier() {
[946]239      typename Container::iterator it;
240      for (it = container.begin(); it != container.end(); ++it) {
241        (*it)->registry = 0;
242      }
243    }
244       
245       
246  protected:
247
248    void attach(ObserverBase& observer) {
249      container.push_back(&observer);
250      observer.registry = this;
251      observer.registry_index = container.size()-1;
252    }
253
254    void detach(ObserverBase& base) {
255      container.back()->registry_index = base.registry_index;
256      container[base.registry_index] = container.back();
257      container.pop_back();
258      base.registry = 0;
259    }
260
261  public:
262       
[1414]263    /// \brief Notifies all the registered observers about an Item added to
264    /// the container.
265    ///
266    /// It notifies all the registered observers about an Item added to
267    /// the container.
[946]268    ///
[1414]269    void add(const Item& item) {
[946]270      typename Container::iterator it;
[1979]271      try {
272        for (it = container.begin(); it != container.end(); ++it) {
273          (*it)->add(item);
274        }
275      } catch (...) {
276        typename Container::iterator jt;
277        for (jt = container.begin(); jt != it; ++it) {
278          (*it)->erase(item);
279        }
280        throw;
[946]281      }
282    }   
283
[1414]284    /// \brief Notifies all the registered observers about more Item added to
285    /// the container.
286    ///
287    /// It notifies all the registered observers about more Item added to
288    /// the container.
289    ///
290    void add(const std::vector<Item>& items) {
291      typename Container::iterator it;
[1979]292      try {
293        for (it = container.begin(); it != container.end(); ++it) {
294          (*it)->add(items);
295        }
296      } catch (...) {
297        typename Container::iterator jt;
298        for (jt = container.begin(); jt != it; ++it) {
299          (*it)->erase(items);
300        }
301        throw;
[1414]302      }
303    }   
304
305    /// \brief Notifies all the registered observers about an Item erased from
306    /// the container.
307    ///
308    /// It notifies all the registered observers about an Item erased from
309    /// the container.
[946]310    ///
311    void erase(const Item& key) {
312      typename Container::iterator it;
313      for (it = container.begin(); it != container.end(); ++it) {
314        (*it)->erase(key);
315      }
316    }
[1414]317
318    /// \brief Notifies all the registered observers about more Item erased 
319    /// from the container.
320    ///
321    /// It notifies all the registered observers about more Item erased from
322    /// the container.
323    ///
324    void erase(const std::vector<Item>& items) {
325      typename Container::iterator it;
326      for (it = container.begin(); it != container.end(); ++it) {
327        (*it)->erase(items);
328      }
329    }
[946]330
[1414]331    /// \brief Notifies all the registered observers about the container is
332    /// built.
333    ///         
[1204]334    /// Notifies all the registered observers about the container is built
[946]335    /// from an empty container.
336    void build() {
337      typename Container::iterator it;
[1979]338      try {
339        for (it = container.begin(); it != container.end(); ++it) {
340          (*it)->build();
341        }
342      } catch (...) {
343        typename Container::iterator jt;
344        for (jt = container.begin(); jt != it; ++it) {
345          (*it)->clear();
346        }
347        throw;
[946]348      }
349    }
350
351
[1414]352    /// \brief Notifies all the registered observers about all Items are
353    /// erased.
354    ///
[946]355    /// Notifies all the registered observers about all Items are erased
356    /// from the container.
357    void clear() {
358      typename Container::iterator it;
359      for (it = container.begin(); it != container.end(); ++it) {
360        (*it)->clear();
361      }
362    }
363  };
364
365 
366/// @}
367 
368
369}
370
371#endif
Note: See TracBrowser for help on using the repository browser.