COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/alteration_notifier.h @ 1989:d276e88aa48a

Last change on this file since 1989:d276e88aa48a was 1989:d276e88aa48a, checked in by Balazs Dezso, 18 years ago

Traits for alteration notifiers
SplitGraph? is temporarly deleted

File size: 10.4 KB
Line 
1/* -*- C++ -*-
2 *
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).
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
19#ifndef LEMON_ALTERATION_NOTIFIER_H
20#define LEMON_ALTERATION_NOTIFIER_H
21
22#include <vector>
23#include <algorithm>
24
25///\ingroup graphmapfactory
26///\file
27///\brief Observer registry for graph alteration observers.
28
29namespace lemon {
30
31  /// \addtogroup graphmapfactory
32  /// @{
33
34  /// \brief Registry class to register objects observes alterations in
35  /// the graph.
36  ///
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
40  /// from the \ref AlterationNotifier::ObserverBase and override
41  /// the virtual functions in that.
42  ///
43  /// The most important application of the alteration observing is the
44  /// dynamic map implementation.
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>
52  class AlterationNotifier {
53  public:
54
55    typedef True Notifier;
56
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
71    /// about the container is built from an empty container or
72    /// is cleared to an empty container.
73    ///
74    /// \author Balazs Dezso
75
76    class ObserverBase {
77    protected:
78      typedef AlterationNotifier Registry;
79
80      friend class AlterationNotifier;
81
82      /// \brief Default constructor.
83      ///
84      /// Default constructor for ObserverBase.
85      ///
86      ObserverBase() : registry(0) {}
87
88      ObserverBase(const ObserverBase& copy) {
89        if (copy.attached()) {
90          copy.getRegistry()->attach(*this);
91        }
92      }
93       
94      virtual ~ObserverBase() {}
95
96      /// \brief Attaches the observer into an AlterationNotifier.
97      ///
98      /// This member attaches the observer into an AlterationNotifier.
99      ///
100      void attach(AlterationNotifier& r) {
101        registry = &r;
102        registry->attach(*this);
103      }
104
105      /// \brief Detaches the observer into an AlterationNotifier.
106      ///
107      /// This member detaches the observer from an AlterationNotifier.
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; }
125
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       
142      virtual void add(const Item&) = 0;
143
144      /// \brief The member function to notificate the observer about
145      /// more item is added to the container.
146      ///
147      /// The add() member function notificates the observer about more item
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      }
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
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.
172      virtual void erase(const std::vector<Item>& items) {
173        for (int i = 0; i < (int)items.size(); ++i) {
174          erase(items[i]);
175        }
176      }
177
178      /// \brief The member function to notificate the observer about the
179      /// container is built.
180      ///
181      /// The build() member function notificates the observer about the
182      /// container is built from an empty container. It have to be
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    ///
211    /// The default constructor of the AlterationNotifier.
212    /// It creates an empty registry.
213    AlterationNotifier() {}
214
215    /// Copy Constructor of the AlterationNotifier.
216       
217    /// Copy constructor of the AlterationNotifier.
218    /// It creates only an empty registry because the copiable
219    /// registry's observers have to be registered still into that registry.
220    AlterationNotifier(const AlterationNotifier&) {}
221
222    /// Assign operator.
223               
224    /// Assign operator for the AlterationNotifier.
225    /// It makes the notifier only empty because the copiable
226    /// notifier's observers have to be registered still into that registry.
227    AlterationNotifier& operator=(const AlterationNotifier&) {
228      typename Container::iterator it;
229      for (it = container.begin(); it != container.end(); ++it) {
230        (*it)->registry = 0;
231      }
232    }
233
234    /// Destructor.
235                               
236    /// Destructor of the AlterationNotifier.
237    ///
238    ~AlterationNotifier() {
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       
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.
268    ///
269    void add(const Item& item) {
270      typename Container::iterator it;
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;
281      }
282    }   
283
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;
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;
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.
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    }
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    }
330
331    /// \brief Notifies all the registered observers about the container is
332    /// built.
333    ///         
334    /// Notifies all the registered observers about the container is built
335    /// from an empty container.
336    void build() {
337      typename Container::iterator it;
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;
348      }
349    }
350
351
352    /// \brief Notifies all the registered observers about all Items are
353    /// erased.
354    ///
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.