2 * lemon/notifier.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Groin on Combinatorial Optimization, 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
23 ///\ingroin graphmapfactory
25 ///\brief Observer registry for graph alteration observers.
29 /// \addtogroin graphmapfactory
32 /// \brief Registry class to register objects observes alterations in
35 /// This class is a registry for the objects which observe the
36 /// alterations in a container. The alteration observers can be attached
37 /// to and detached from the registry. The observers have to inherit
38 /// from the \ref AlterationNotifier::ObserverBase and override
39 /// the virtual functions in that.
41 /// The most important application of the alteration observing is the
42 /// dynamic map implementation.
44 /// \param _Item The item type what the observers are observing, usually
47 /// \author Balazs Dezso
49 template <typename _Item>
50 class AlterationNotifier {
54 /// ObserverBase is the base class for the observers.
56 /// ObserverBase is the abstract base class for the observers.
57 /// It will be notified about an item was inserted into or
58 /// erased from the graph.
60 /// The observer interface contains some pure virtual functions
61 /// to override. The add() and erase() functions are
62 /// to notify the oberver when one item is added or
65 /// The build() and clear() members are to notify the observer
66 /// about the container is built from an empty container or
67 /// is cleared to an empty container.
69 /// \author Balazs Dezso
73 typedef AlterationNotifier Registry;
75 friend class AlterationNotifier;
77 /// \brief Default constructor.
79 /// Default constructor for ObserverBase.
81 ObserverBase() : registry(0) {}
83 ObserverBase(const ObserverBase& copy) {
84 if (copy.attached()) {
85 copy.getRegistry()->attach(*this);
89 virtual ~ObserverBase() {}
91 /// \brief Attaches the observer into an AlterationNotifier.
93 /// This member attaches the observer into an AlterationNotifier.
95 void attach(AlterationNotifier& r) {
97 registry->attach(*this);
100 /// \brief Detaches the observer into an AlterationNotifier.
102 /// This member detaches the observer from an AlterationNotifier.
106 registry->detach(*this);
111 /// Gives back a pointer to the registry what the map attached into.
113 /// This function gives back a pointer to the registry what the map
116 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
118 /// Gives back true when the observer is attached into a registry.
119 bool attached() const { return registry != 0; }
123 ObserverBase& operator=(const ObserverBase& copy);
130 /// \brief The member function to notificate the observer about an
131 /// item is added to the container.
133 /// The add() member function notificates the observer about an item
134 /// is added to the container. It have to be overrided in the
137 virtual void add(const Item&) = 0;
139 /// \brief The member function to notificate the observer about
140 /// more item is added to the container.
142 /// The add() member function notificates the observer about more item
143 /// is added to the container. It have to be overrided in the
146 virtual void add(const std::vector<Item>& items) {
147 for (int i = 0; i < (int)items.size(); ++i) {
152 /// \brief The member function to notificate the observer about an
153 /// item is erased from the container.
155 /// The erase() member function notificates the observer about an
156 /// item is erased from the container. It have to be overrided in
159 virtual void erase(const Item&) = 0;
161 /// \brief The member function to notificate the observer about
162 /// more item is erased from the container.
164 /// The erase() member function notificates the observer about more item
165 /// is erased from the container. It have to be overrided in the
167 virtual void erase(const std::vector<Item>& items) {
168 for (int i = 0; i < (int)items.size(); ++i) {
173 /// \brief The member function to notificate the observer about the
174 /// container is built.
176 /// The build() member function notificates the observer about the
177 /// container is built from an empty container. It have to be
178 /// overrided in the subclasses.
180 virtual void build() = 0;
182 /// \brief The member function to notificate the observer about all
183 /// items are erased from the container.
185 /// The clear() member function notificates the observer about all
186 /// items are erased from the container. It have to be overrided in
189 virtual void clear() = 0;
196 typedef std::vector<ObserverBase*> Container;
203 /// Default constructor.
206 /// The default constructor of the AlterationNotifier.
207 /// It creates an empty registry.
208 AlterationNotifier() {}
210 /// Copy Constructor of the AlterationNotifier.
212 /// Copy constructor of the AlterationNotifier.
213 /// It creates only an empty registry because the copiable
214 /// registry's observers have to be registered still into that registry.
215 AlterationNotifier(const AlterationNotifier&) {}
219 /// Assign operator for the AlterationNotifier.
220 /// It makes the notifier only empty because the copiable
221 /// notifier's observers have to be registered still into that registry.
222 AlterationNotifier& operator=(const AlterationNotifier&) {
223 typename Container::iterator it;
224 for (it = container.begin(); it != container.end(); ++it) {
231 /// Destructor of the AlterationNotifier.
233 ~AlterationNotifier() {
234 typename Container::iterator it;
235 for (it = container.begin(); it != container.end(); ++it) {
243 void attach(ObserverBase& observer) {
244 container.push_back(&observer);
245 observer.registry = this;
246 observer.registry_index = container.size()-1;
249 void detach(ObserverBase& base) {
250 container.back()->registry_index = base.registry_index;
251 container[base.registry_index] = container.back();
252 container.pop_back();
258 /// \brief Notifies all the registered observers about an Item added to
261 /// It notifies all the registered observers about an Item added to
264 void add(const Item& item) {
265 typename Container::iterator it;
266 for (it = container.begin(); it != container.end(); ++it) {
271 /// \brief Notifies all the registered observers about more Item added to
274 /// It notifies all the registered observers about more Item added to
277 void add(const std::vector<Item>& items) {
278 typename Container::iterator it;
279 for (it = container.begin(); it != container.end(); ++it) {
284 /// \brief Notifies all the registered observers about an Item erased from
287 /// It notifies all the registered observers about an Item erased from
290 void erase(const Item& key) {
291 typename Container::iterator it;
292 for (it = container.begin(); it != container.end(); ++it) {
297 /// \brief Notifies all the registered observers about more Item erased
298 /// from the container.
300 /// It notifies all the registered observers about more Item erased from
303 void erase(const std::vector<Item>& items) {
304 typename Container::iterator it;
305 for (it = container.begin(); it != container.end(); ++it) {
310 /// \brief Notifies all the registered observers about the container is
313 /// Notifies all the registered observers about the container is built
314 /// from an empty container.
316 typename Container::iterator it;
317 for (it = container.begin(); it != container.end(); ++it) {
323 /// \brief Notifies all the registered observers about all Items are
326 /// Notifies all the registered observers about all Items are erased
327 /// from the container.
329 typename Container::iterator it;
330 for (it = container.begin(); it != container.end(); ++it) {
337 /// \brief Class to extend a graph with the functionality of alteration
340 /// AlterableGraphExtender extends the _Base graphs functionality with
341 /// the possibility of alteration observing. It defines two observer
342 /// registrys for the nodes and mapes.
344 /// \todo Document what "alteration observing" is. And probably find a
345 /// better (shorter) name.
347 /// \param _Base is the base class to extend.
349 /// \pre _Base is conform to the BaseGraphComponent concept.
351 /// \post AlterableGraphExtender<_Base> is conform to the
352 /// AlterableGraphComponent concept.
354 /// \author Balazs Dezso
356 template <typename _Base>
357 class AlterableGraphExtender : public _Base {
360 typedef AlterableGraphExtender Graph;
361 typedef _Base Parent;
363 typedef typename Parent::Node Node;
364 typedef typename Parent::Edge Edge;
366 /// The edge observer registry.
367 typedef AlterationNotifier<Edge> EdgeNotifier;
368 /// The node observer registry.
369 typedef AlterationNotifier<Node> NodeNotifier;
374 mutable EdgeNotifier edge_notifier;
376 mutable NodeNotifier node_notifier;
380 /// \brief Gives back the edge alteration notifier.
382 /// Gives back the edge alteration notifier.
383 EdgeNotifier& getNotifier(Edge) const {
384 return edge_notifier;
387 /// \brief Gives back the node alteration notifier.
389 /// Gives back the node alteration notifier.
390 NodeNotifier& getNotifier(Node) const {
391 return node_notifier;
394 ~AlterableGraphExtender() {
395 node_notifier.clear();
396 edge_notifier.clear();
402 template <typename _Base>
403 class AlterableEdgeSetExtender : public _Base {
406 typedef AlterableEdgeSetExtender Graph;
407 typedef _Base Parent;
409 typedef typename Parent::Edge Edge;
411 /// The edge observer registry.
412 typedef AlterationNotifier<Edge> EdgeNotifier;
416 mutable EdgeNotifier edge_notifier;
420 /// \brief Gives back the edge alteration notifier.
422 /// Gives back the edge alteration notifier.
423 EdgeNotifier& getNotifier(Edge) const {
424 return edge_notifier;
427 ~AlterableEdgeSetExtender() {
428 edge_notifier.clear();
433 /// \brief Class to extend an undirected graph with the functionality of
434 /// alteration observing.
438 /// \sa AlterableGraphExtender
440 /// \bug This should be done some other way. Possibilities: template
441 /// specialization (not very easy, if at all possible); some kind of
442 /// enable_if boost technique?
444 template <typename _Base>
445 class AlterableUGraphExtender
446 : public AlterableGraphExtender<_Base> {
449 typedef AlterableUGraphExtender Graph;
450 typedef AlterableGraphExtender<_Base> Parent;
452 typedef typename Parent::UEdge UEdge;
454 /// The edge observer registry.
455 typedef AlterationNotifier<UEdge> UEdgeNotifier;
459 mutable UEdgeNotifier u_edge_notifier;
463 using Parent::getNotifier;
464 UEdgeNotifier& getNotifier(UEdge) const {
465 return u_edge_notifier;
468 ~AlterableUGraphExtender() {
469 u_edge_notifier.clear();
473 template <typename _Base>
474 class AlterableUEdgeSetExtender
475 : public AlterableEdgeSetExtender<_Base> {
478 typedef AlterableUEdgeSetExtender Graph;
479 typedef AlterableEdgeSetExtender<_Base> Parent;
481 typedef typename Parent::UEdge UEdge;
483 typedef AlterationNotifier<UEdge> UEdgeNotifier;
487 mutable UEdgeNotifier u_edge_notifier;
491 using Parent::getNotifier;
492 UEdgeNotifier& getNotifier(UEdge) const {
493 return u_edge_notifier;
496 ~AlterableUEdgeSetExtender() {
497 u_edge_notifier.clear();
503 template <typename _Base>
504 class AlterableBpUGraphExtender : public _Base {
507 typedef _Base Parent;
508 typedef AlterableBpUGraphExtender Graph;
510 typedef typename Parent::Node Node;
511 typedef typename Parent::BNode BNode;
512 typedef typename Parent::ANode ANode;
513 typedef typename Parent::Edge Edge;
514 typedef typename Parent::UEdge UEdge;
517 typedef AlterationNotifier<Node> NodeNotifier;
518 typedef AlterationNotifier<BNode> BNodeNotifier;
519 typedef AlterationNotifier<ANode> ANodeNotifier;
520 typedef AlterationNotifier<Edge> EdgeNotifier;
521 typedef AlterationNotifier<UEdge> UEdgeNotifier;
525 mutable NodeNotifier nodeNotifier;
526 mutable BNodeNotifier bNodeNotifier;
527 mutable ANodeNotifier aNodeNotifier;
528 mutable EdgeNotifier edgeNotifier;
529 mutable UEdgeNotifier uEdgeNotifier;
533 NodeNotifier& getNotifier(Node) const {
537 BNodeNotifier& getNotifier(BNode) const {
538 return bNodeNotifier;
541 ANodeNotifier& getNotifier(ANode) const {
542 return aNodeNotifier;
545 EdgeNotifier& getNotifier(Edge) const {
549 UEdgeNotifier& getNotifier(UEdge) const {
550 return uEdgeNotifier;
553 ~AlterableBpUGraphExtender() {
554 nodeNotifier.clear();
555 bNodeNotifier.clear();
556 aNodeNotifier.clear();
557 edgeNotifier.clear();
558 uEdgeNotifier.clear();