2 * src/lemon/notifier.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
18 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
25 ///\brief Observer registry for graph alteration observers.
31 /// \addtogroup graphmaps
34 /// Registry class to register objects observes alterations in the graph.
36 /// This class is a registry for the objects which observe the
37 /// alterations in a container. The alteration observers can be attached
38 /// to and detached from the registry. The observers have to inherit
39 /// from the \ref AlterationNotifier::ObserverBase and override
40 /// the virtual functions in that.
42 /// The most important application of the alteration observing is the
43 /// dynamic map implementation when the observers are observing the
44 /// alterations in the graph.
46 /// \param _Item The item type what the observers are observing, usually
49 /// \author Balazs Dezso
51 template <typename _Item>
52 class AlterationNotifier {
56 /// ObserverBase is the base class for the observers.
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.
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
67 /// The build() and clear() members are to notify the observer
68 /// about the container is builded from an empty container or
69 /// is cleared to an empty container.
71 /// \author Balazs Dezso
75 typedef AlterationNotifier Registry;
77 friend class AlterationNotifier;
79 /// Default constructor.
81 /// Default constructor for ObserverBase.
83 ObserverBase() : registry(0) {}
85 virtual ~ObserverBase() {}
87 /// Attaches the observer into an AlterationNotifier.
89 /// This member attaches the observer into an AlterationNotifier.
91 void attach(AlterationNotifier& r) {
93 registry->attach(*this);
96 /// Detaches the observer into an AlterationNotifier.
98 /// This member detaches the observer from an AlterationNotifier.
102 registry->detach(*this);
107 /// Gives back a pointer to the registry what the map attached into.
109 /// This function gives back a pointer to the registry what the map
112 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
114 /// Gives back true when the observer is attached into a registry.
115 bool attached() const { return registry != 0; }
119 ObserverBase(const ObserverBase& copy);
120 ObserverBase& operator=(const ObserverBase& copy);
129 /// \brief The member function to notificate the observer about an
130 /// item is added to the container.
132 /// The add() member function notificates the observer about an item
133 /// is added to the container. It have to be overrided in the
136 virtual void add(const Item&) = 0;
139 /// \brief The member function to notificate the observer about an
140 /// item is erased from the container.
142 /// The erase() member function notificates the observer about an
143 /// item is erased from the container. It have to be overrided in
146 virtual void erase(const Item&) = 0;
148 /// \brief The member function to notificate the observer about the
149 /// container is builded.
151 /// The build() member function notificates the observer about the
152 /// container is builded from an empty container. It have to be
153 /// overrided in the subclasses.
155 virtual void build() = 0;
157 /// \brief The member function to notificate the observer about all
158 /// items are erased from the container.
160 /// The clear() member function notificates the observer about all
161 /// items are erased from the container. It have to be overrided in
164 virtual void clear() = 0;
171 typedef std::vector<ObserverBase*> Container;
178 /// Default constructor.
181 /// The default constructor of the AlterationNotifier.
182 /// It creates an empty registry.
183 AlterationNotifier() {}
185 /// Copy Constructor of the AlterationNotifier.
187 /// Copy constructor of the AlterationNotifier.
188 /// It creates only an empty registry because the copiable
189 /// registry's observers have to be registered still into that registry.
190 AlterationNotifier(const AlterationNotifier&) {}
194 /// Assign operator for the AlterationNotifier.
195 /// It makes the notifier only empty because the copiable
196 /// notifier's observers have to be registered still into that registry.
197 AlterationNotifier& operator=(const AlterationNotifier&) {
198 typename Container::iterator it;
199 for (it = container.begin(); it != container.end(); ++it) {
206 /// Destructor of the AlterationNotifier.
208 ~AlterationNotifier() {
209 typename Container::iterator it;
210 for (it = container.begin(); it != container.end(); ++it) {
218 void attach(ObserverBase& observer) {
219 container.push_back(&observer);
220 observer.registry = this;
221 observer.registry_index = container.size()-1;
224 void detach(ObserverBase& base) {
225 container.back()->registry_index = base.registry_index;
226 container[base.registry_index] = container.back();
227 container.pop_back();
233 /// Notifies all the registered observers about an Item added to the container.
235 /// It notifies all the registered observers about an Item added to the container.
237 void add(const Item& key) {
238 typename Container::iterator it;
239 for (it = container.begin(); it != container.end(); ++it) {
244 /// Notifies all the registered observers about an Item erased from the container.
246 /// It notifies all the registered observers about an Item erased from the container.
248 void erase(const Item& key) {
249 typename Container::iterator it;
250 for (it = container.begin(); it != container.end(); ++it) {
256 /// Notifies all the registered observers about the container is builded.
258 /// Notifies all the registered observers about the container is builded
259 /// from an empty container.
261 typename Container::iterator it;
262 for (it = container.begin(); it != container.end(); ++it) {
268 /// Notifies all the registered observers about all Items are erased.
270 /// Notifies all the registered observers about all Items are erased
271 /// from the container.
273 typename Container::iterator it;
274 for (it = container.begin(); it != container.end(); ++it) {
281 /// \brief Class to extend a graph with the functionality of alteration
284 /// AlterableGraphExtender extends the _Base graphs functionality with
285 /// the possibility of alteration observing. It defines two observer
286 /// registrys for the nodes and mapes.
288 /// \todo Document what "alteration observing" is. And probably find a
289 /// better (shorter) name.
291 /// \param _Base is the base class to extend.
293 /// \pre _Base is conform to the BaseGraphComponent concept.
295 /// \post AlterableGraphExtender<_Base> is conform to the
296 /// AlterableGraphComponent concept.
298 /// \author Balazs Dezso
300 template <typename _Base>
301 class AlterableGraphExtender : public _Base {
304 typedef AlterableGraphExtender Graph;
305 typedef _Base Parent;
307 typedef typename Parent::Node Node;
308 typedef typename Parent::Edge Edge;
310 /// The edge observer registry.
311 typedef AlterationNotifier<Edge> EdgeNotifier;
312 /// The node observer registry.
313 typedef AlterationNotifier<Node> NodeNotifier;
318 mutable EdgeNotifier edge_notifier;
320 mutable NodeNotifier node_notifier;
324 EdgeNotifier& getNotifier(Edge = INVALID) const {
325 return edge_notifier;
328 NodeNotifier& getNotifier(Node = INVALID) const {
329 return node_notifier;
332 ~AlterableGraphExtender() {
333 node_notifier.clear();
334 edge_notifier.clear();
339 /// \brief Class to extend an undirected graph with the functionality of
340 /// alteration observing.
344 /// \sa AlterableGraphExtender
346 /// \bug This should be done some other way. Possibilities: template
347 /// specialization (not very easy, if at all possible); some kind of
348 /// enable_if boost technique?
350 template <typename _Base>
351 class AlterableUndirGraphExtender
352 : public AlterableGraphExtender<_Base> {
355 typedef AlterableUndirGraphExtender Graph;
356 typedef AlterableGraphExtender<_Base> Parent;
358 typedef typename Parent::UndirEdge UndirEdge;
360 /// The edge observer registry.
361 typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
365 mutable UndirEdgeNotifier undir_edge_notifier;
369 using Parent::getNotifier;
370 UndirEdgeNotifier& getNotifier(UndirEdge) const {
371 return undir_edge_notifier;
374 ~AlterableUndirGraphExtender() {
375 undir_edge_notifier.clear();