COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/alteration_notifier.h @ 1979:c2992fd74dad

Last change on this file since 1979:c2992fd74dad was 1979:c2992fd74dad, checked in by Balazs Dezso, 14 years ago

Mergeing extendermerge branch
Changes:

the extender system
resize for static size graph
UGraphExtender => UndirectGraphExtender?

UGraphExtenders with changed meaning

Some UGraphExtender /SubUGraphExtenders, DirectUGraphExtender/
GridGraph? => GridUGraph
radix sort to ansi compatible

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_OBSERVER_REGISTRY_H
20#define LEMON_ALTERATION_OBSERVER_REGISTRY_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  /// \addtogroin 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    typedef _Item Item;
55
56    /// ObserverBase is the base class for the observers.
57       
58    /// ObserverBase is the abstract base class for the observers.
59    /// It will be notified about an item was inserted into or
60    /// erased from the graph.
61    ///
62    /// The observer interface contains some pure virtual functions
63    /// to override. The add() and erase() functions are
64    /// to notify the oberver when one item is added or
65    /// erased.
66    ///
67    /// The build() and clear() members are to notify the observer
68    /// about the container is built from an empty container or
69    /// is cleared to an empty container.
70    ///
71    /// \author Balazs Dezso
72
73    class ObserverBase {
74    protected:
75      typedef AlterationNotifier Registry;
76
77      friend class AlterationNotifier;
78
79      /// \brief Default constructor.
80      ///
81      /// Default constructor for ObserverBase.
82      ///
83      ObserverBase() : registry(0) {}
84
85      ObserverBase(const ObserverBase& copy) {
86        if (copy.attached()) {
87          copy.getRegistry()->attach(*this);
88        }
89      }
90       
91      virtual ~ObserverBase() {}
92
93      /// \brief Attaches the observer into an AlterationNotifier.
94      ///
95      /// This member attaches the observer into an AlterationNotifier.
96      ///
97      void attach(AlterationNotifier& r) {
98        registry = &r;
99        registry->attach(*this);
100      }
101
102      /// \brief Detaches the observer into an AlterationNotifier.
103      ///
104      /// This member detaches the observer from an AlterationNotifier.
105      ///
106      void detach() {
107        if (registry) {
108          registry->detach(*this);
109        }
110      }
111       
112
113      /// Gives back a pointer to the registry what the map attached into.
114
115      /// This function gives back a pointer to the registry what the map
116      /// attached into.
117      ///
118      Registry* getRegistry() const { return const_cast<Registry*>(registry); }
119     
120      /// Gives back true when the observer is attached into a registry.
121      bool attached() const { return registry != 0; }
122
123    private:
124
125      ObserverBase& operator=(const ObserverBase& copy);
126
127    protected:
128     
129      Registry* registry;
130      int registry_index;
131
132      /// \brief The member function to notificate the observer about an
133      /// item is added to the container.
134      ///
135      /// The add() member function notificates the observer about an item
136      /// is added to the container. It have to be overrided in the
137      /// subclasses.
138       
139      virtual void add(const Item&) = 0;
140
141      /// \brief The member function to notificate the observer about
142      /// more item is added to the container.
143      ///
144      /// The add() member function notificates the observer about more item
145      /// is added to the container. It have to be overrided in the
146      /// subclasses.
147
148      virtual void add(const std::vector<Item>& items) {
149        for (int i = 0; i < (int)items.size(); ++i) {
150          add(items[i]);
151        }
152      }
153
154      /// \brief The member function to notificate the observer about an
155      /// item is erased from the container.
156      ///
157      /// The erase() member function notificates the observer about an
158      /// item is erased from the container. It have to be overrided in
159      /// the subclasses.
160       
161      virtual void erase(const Item&) = 0;
162
163      /// \brief The member function to notificate the observer about
164      /// more item is erased from the container.
165      ///
166      /// The erase() member function notificates the observer about more item
167      /// is erased from the container. It have to be overrided in the
168      /// subclasses.
169      virtual void erase(const std::vector<Item>& items) {
170        for (int i = 0; i < (int)items.size(); ++i) {
171          erase(items[i]);
172        }
173      }
174
175      /// \brief The member function to notificate the observer about the
176      /// container is built.
177      ///
178      /// The build() member function notificates the observer about the
179      /// container is built from an empty container. It have to be
180      /// overrided in the subclasses.
181
182      virtual void build() = 0;
183
184      /// \brief The member function to notificate the observer about all
185      /// items are erased from the container.
186      ///
187      /// The clear() member function notificates the observer about all
188      /// items are erased from the container. It have to be overrided in
189      /// the subclasses.
190     
191      virtual void clear() = 0;
192
193    };
194       
195  protected:
196       
197
198    typedef std::vector<ObserverBase*> Container;
199
200    Container container;
201
202               
203  public:
204
205    /// Default constructor.
206       
207    ///
208    /// The default constructor of the AlterationNotifier.
209    /// It creates an empty registry.
210    AlterationNotifier() {}
211
212    /// Copy Constructor of the AlterationNotifier.
213       
214    /// Copy constructor of the AlterationNotifier.
215    /// It creates only an empty registry because the copiable
216    /// registry's observers have to be registered still into that registry.
217    AlterationNotifier(const AlterationNotifier&) {}
218
219    /// Assign operator.
220               
221    /// Assign operator for the AlterationNotifier.
222    /// It makes the notifier only empty because the copiable
223    /// notifier's observers have to be registered still into that registry.
224    AlterationNotifier& operator=(const AlterationNotifier&) {
225      typename Container::iterator it;
226      for (it = container.begin(); it != container.end(); ++it) {
227        (*it)->registry = 0;
228      }
229    }
230
231    /// Destructor.
232                               
233    /// Destructor of the AlterationNotifier.
234    ///
235    ~AlterationNotifier() {
236      typename Container::iterator it;
237      for (it = container.begin(); it != container.end(); ++it) {
238        (*it)->registry = 0;
239      }
240    }
241       
242       
243  protected:
244
245    void attach(ObserverBase& observer) {
246      container.push_back(&observer);
247      observer.registry = this;
248      observer.registry_index = container.size()-1;
249    }
250
251    void detach(ObserverBase& base) {
252      container.back()->registry_index = base.registry_index;
253      container[base.registry_index] = container.back();
254      container.pop_back();
255      base.registry = 0;
256    }
257
258  public:
259       
260    /// \brief Notifies all the registered observers about an Item added to
261    /// the container.
262    ///
263    /// It notifies all the registered observers about an Item added to
264    /// the container.
265    ///
266    void add(const Item& item) {
267      typename Container::iterator it;
268      try {
269        for (it = container.begin(); it != container.end(); ++it) {
270          (*it)->add(item);
271        }
272      } catch (...) {
273        typename Container::iterator jt;
274        for (jt = container.begin(); jt != it; ++it) {
275          (*it)->erase(item);
276        }
277        throw;
278      }
279    }   
280
281    /// \brief Notifies all the registered observers about more Item added to
282    /// the container.
283    ///
284    /// It notifies all the registered observers about more Item added to
285    /// the container.
286    ///
287    void add(const std::vector<Item>& items) {
288      typename Container::iterator it;
289      try {
290        for (it = container.begin(); it != container.end(); ++it) {
291          (*it)->add(items);
292        }
293      } catch (...) {
294        typename Container::iterator jt;
295        for (jt = container.begin(); jt != it; ++it) {
296          (*it)->erase(items);
297        }
298        throw;
299      }
300    }   
301
302    /// \brief Notifies all the registered observers about an Item erased from
303    /// the container.
304    ///
305    /// It notifies all the registered observers about an Item erased from
306    /// the container.
307    ///
308    void erase(const Item& key) {
309      typename Container::iterator it;
310      for (it = container.begin(); it != container.end(); ++it) {
311        (*it)->erase(key);
312      }
313    }
314
315    /// \brief Notifies all the registered observers about more Item erased 
316    /// from the container.
317    ///
318    /// It notifies all the registered observers about more Item erased from
319    /// the container.
320    ///
321    void erase(const std::vector<Item>& items) {
322      typename Container::iterator it;
323      for (it = container.begin(); it != container.end(); ++it) {
324        (*it)->erase(items);
325      }
326    }
327
328    /// \brief Notifies all the registered observers about the container is
329    /// built.
330    ///         
331    /// Notifies all the registered observers about the container is built
332    /// from an empty container.
333    void build() {
334      typename Container::iterator it;
335      try {
336        for (it = container.begin(); it != container.end(); ++it) {
337          (*it)->build();
338        }
339      } catch (...) {
340        typename Container::iterator jt;
341        for (jt = container.begin(); jt != it; ++it) {
342          (*it)->clear();
343        }
344        throw;
345      }
346    }
347
348
349    /// \brief Notifies all the registered observers about all Items are
350    /// erased.
351    ///
352    /// Notifies all the registered observers about all Items are erased
353    /// from the container.
354    void clear() {
355      typename Container::iterator it;
356      for (it = container.begin(); it != container.end(); ++it) {
357        (*it)->clear();
358      }
359    }
360  };
361
362 
363/// @}
364 
365
366}
367
368#endif
Note: See TracBrowser for help on using the repository browser.