3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_ALTERATION_NOTIFIER_H
20 #define LEMON_ALTERATION_NOTIFIER_H
25 ///\ingroup graphmapfactory
27 ///\brief Observer registry for graph alteration observers.
31 /// \addtogroup graphmapfactory
34 /// \brief Registry class to register objects observes alterations in
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.
43 /// The most important application of the alteration observing is the
44 /// dynamic map implementation.
46 /// \param _Item The item type what the observers are observing, usually
49 /// \author Balazs Dezso
51 template <typename _Item>
52 class AlterationNotifier {
55 typedef True Notifier;
59 /// ObserverBase is the base class for the observers.
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.
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
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.
74 /// \author Balazs Dezso
78 typedef AlterationNotifier Registry;
80 friend class AlterationNotifier;
82 /// \brief Default constructor.
84 /// Default constructor for ObserverBase.
86 ObserverBase() : registry(0) {}
88 ObserverBase(const ObserverBase& copy) {
89 if (copy.attached()) {
90 copy.getRegistry()->attach(*this);
94 virtual ~ObserverBase() {}
96 /// \brief Attaches the observer into an AlterationNotifier.
98 /// This member attaches the observer into an AlterationNotifier.
100 void attach(AlterationNotifier& r) {
102 registry->attach(*this);
105 /// \brief Detaches the observer into an AlterationNotifier.
107 /// This member detaches the observer from an AlterationNotifier.
111 registry->detach(*this);
116 /// Gives back a pointer to the registry what the map attached into.
118 /// This function gives back a pointer to the registry what the map
121 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
123 /// Gives back true when the observer is attached into a registry.
124 bool attached() const { return registry != 0; }
128 ObserverBase& operator=(const ObserverBase& copy);
135 /// \brief The member function to notificate the observer about an
136 /// item is added to the container.
138 /// The add() member function notificates the observer about an item
139 /// is added to the container. It have to be overrided in the
142 virtual void add(const Item&) = 0;
144 /// \brief The member function to notificate the observer about
145 /// more item is added to the container.
147 /// The add() member function notificates the observer about more item
148 /// is added to the container. It have to be overrided in the
151 virtual void add(const std::vector<Item>& items) {
152 for (int i = 0; i < (int)items.size(); ++i) {
157 /// \brief The member function to notificate the observer about an
158 /// item is erased from the container.
160 /// The erase() member function notificates the observer about an
161 /// item is erased from the container. It have to be overrided in
164 virtual void erase(const Item&) = 0;
166 /// \brief The member function to notificate the observer about
167 /// more item is erased from the container.
169 /// The erase() member function notificates the observer about more item
170 /// is erased from the container. It have to be overrided in the
172 virtual void erase(const std::vector<Item>& items) {
173 for (int i = 0; i < (int)items.size(); ++i) {
178 /// \brief The member function to notificate the observer about the
179 /// container is built.
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.
185 virtual void build() = 0;
187 /// \brief The member function to notificate the observer about all
188 /// items are erased from the container.
190 /// The clear() member function notificates the observer about all
191 /// items are erased from the container. It have to be overrided in
194 virtual void clear() = 0;
201 typedef std::vector<ObserverBase*> Container;
208 /// Default constructor.
211 /// The default constructor of the AlterationNotifier.
212 /// It creates an empty registry.
213 AlterationNotifier() {}
215 /// Copy Constructor of the AlterationNotifier.
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&) {}
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) {
236 /// Destructor of the AlterationNotifier.
238 ~AlterationNotifier() {
239 typename Container::iterator it;
240 for (it = container.begin(); it != container.end(); ++it) {
248 void attach(ObserverBase& observer) {
249 container.push_back(&observer);
250 observer.registry = this;
251 observer.registry_index = container.size()-1;
254 void detach(ObserverBase& base) {
255 container.back()->registry_index = base.registry_index;
256 container[base.registry_index] = container.back();
257 container.pop_back();
263 /// \brief Notifies all the registered observers about an Item added to
266 /// It notifies all the registered observers about an Item added to
269 void add(const Item& item) {
270 typename Container::iterator it;
272 for (it = container.begin(); it != container.end(); ++it) {
276 typename Container::iterator jt;
277 for (jt = container.begin(); jt != it; ++it) {
284 /// \brief Notifies all the registered observers about more Item added to
287 /// It notifies all the registered observers about more Item added to
290 void add(const std::vector<Item>& items) {
291 typename Container::iterator it;
293 for (it = container.begin(); it != container.end(); ++it) {
297 typename Container::iterator jt;
298 for (jt = container.begin(); jt != it; ++it) {
305 /// \brief Notifies all the registered observers about an Item erased from
308 /// It notifies all the registered observers about an Item erased from
311 void erase(const Item& key) {
312 typename Container::iterator it;
313 for (it = container.begin(); it != container.end(); ++it) {
318 /// \brief Notifies all the registered observers about more Item erased
319 /// from the container.
321 /// It notifies all the registered observers about more Item erased from
324 void erase(const std::vector<Item>& items) {
325 typename Container::iterator it;
326 for (it = container.begin(); it != container.end(); ++it) {
331 /// \brief Notifies all the registered observers about the container is
334 /// Notifies all the registered observers about the container is built
335 /// from an empty container.
337 typename Container::iterator it;
339 for (it = container.begin(); it != container.end(); ++it) {
343 typename Container::iterator jt;
344 for (jt = container.begin(); jt != it; ++it) {
352 /// \brief Notifies all the registered observers about all Items are
355 /// Notifies all the registered observers about all Items are erased
356 /// from the container.
358 typename Container::iterator it;
359 for (it = container.begin(); it != container.end(); ++it) {