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_OBSERVER_REGISTRY_H
20 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
25 ///\ingroup graphmapfactory
27 ///\brief Observer registry for graph alteration observers.
31 /// \addtogroin 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 {
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 built 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 /// \brief Default constructor.
81 /// Default constructor for ObserverBase.
83 ObserverBase() : registry(0) {}
85 ObserverBase(const ObserverBase& copy) {
86 if (copy.attached()) {
87 copy.getRegistry()->attach(*this);
91 virtual ~ObserverBase() {}
93 /// \brief Attaches the observer into an AlterationNotifier.
95 /// This member attaches the observer into an AlterationNotifier.
97 void attach(AlterationNotifier& r) {
99 registry->attach(*this);
102 /// \brief Detaches the observer into an AlterationNotifier.
104 /// This member detaches the observer from an AlterationNotifier.
108 registry->detach(*this);
113 /// Gives back a pointer to the registry what the map attached into.
115 /// This function gives back a pointer to the registry what the map
118 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
120 /// Gives back true when the observer is attached into a registry.
121 bool attached() const { return registry != 0; }
125 ObserverBase& operator=(const ObserverBase& copy);
132 /// \brief The member function to notificate the observer about an
133 /// item is added to the container.
135 /// The add() member function notificates the observer about an item
136 /// is added to the container. It have to be overrided in the
139 virtual void add(const Item&) = 0;
141 /// \brief The member function to notificate the observer about
142 /// more item is added to the container.
144 /// The add() member function notificates the observer about more item
145 /// is added to the container. It have to be overrided in the
148 virtual void add(const std::vector<Item>& items) {
149 for (int i = 0; i < (int)items.size(); ++i) {
154 /// \brief The member function to notificate the observer about an
155 /// item is erased from the container.
157 /// The erase() member function notificates the observer about an
158 /// item is erased from the container. It have to be overrided in
161 virtual void erase(const Item&) = 0;
163 /// \brief The member function to notificate the observer about
164 /// more item is erased from the container.
166 /// The erase() member function notificates the observer about more item
167 /// is erased from the container. It have to be overrided in the
169 virtual void erase(const std::vector<Item>& items) {
170 for (int i = 0; i < (int)items.size(); ++i) {
175 /// \brief The member function to notificate the observer about the
176 /// container is built.
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.
182 virtual void build() = 0;
184 /// \brief The member function to notificate the observer about all
185 /// items are erased from the container.
187 /// The clear() member function notificates the observer about all
188 /// items are erased from the container. It have to be overrided in
191 virtual void clear() = 0;
198 typedef std::vector<ObserverBase*> Container;
205 /// Default constructor.
208 /// The default constructor of the AlterationNotifier.
209 /// It creates an empty registry.
210 AlterationNotifier() {}
212 /// Copy Constructor of the AlterationNotifier.
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&) {}
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) {
233 /// Destructor of the AlterationNotifier.
235 ~AlterationNotifier() {
236 typename Container::iterator it;
237 for (it = container.begin(); it != container.end(); ++it) {
245 void attach(ObserverBase& observer) {
246 container.push_back(&observer);
247 observer.registry = this;
248 observer.registry_index = container.size()-1;
251 void detach(ObserverBase& base) {
252 container.back()->registry_index = base.registry_index;
253 container[base.registry_index] = container.back();
254 container.pop_back();
260 /// \brief Notifies all the registered observers about an Item added to
263 /// It notifies all the registered observers about an Item added to
266 void add(const Item& item) {
267 typename Container::iterator it;
268 for (it = container.begin(); it != container.end(); ++it) {
273 /// \brief Notifies all the registered observers about more Item added to
276 /// It notifies all the registered observers about more Item added to
279 void add(const std::vector<Item>& items) {
280 typename Container::iterator it;
281 for (it = container.begin(); it != container.end(); ++it) {
286 /// \brief Notifies all the registered observers about an Item erased from
289 /// It notifies all the registered observers about an Item erased from
292 void erase(const Item& key) {
293 typename Container::iterator it;
294 for (it = container.begin(); it != container.end(); ++it) {
299 /// \brief Notifies all the registered observers about more Item erased
300 /// from the container.
302 /// It notifies all the registered observers about more Item erased from
305 void erase(const std::vector<Item>& items) {
306 typename Container::iterator it;
307 for (it = container.begin(); it != container.end(); ++it) {
312 /// \brief Notifies all the registered observers about the container is
315 /// Notifies all the registered observers about the container is built
316 /// from an empty container.
318 typename Container::iterator it;
319 for (it = container.begin(); it != container.end(); ++it) {
325 /// \brief Notifies all the registered observers about all Items are
328 /// Notifies all the registered observers about all Items are erased
329 /// from the container.
331 typename Container::iterator it;
332 for (it = container.begin(); it != container.end(); ++it) {
339 /// \brief Class to extend a graph with the functionality of alteration
342 /// AlterableGraphExtender extends the _Base graphs functionality with
343 /// the possibility of alteration observing. It defines two observer
344 /// registrys for the nodes and mapes.
346 /// \todo Document what "alteration observing" is. And probably find a
347 /// better (shorter) name.
349 /// \param _Base is the base class to extend.
351 /// \pre _Base is conform to the BaseGraphComponent concept.
353 /// \post AlterableGraphExtender<_Base> is conform to the
354 /// AlterableGraphComponent concept.
356 /// \author Balazs Dezso
358 template <typename _Base>
359 class AlterableGraphExtender : public _Base {
362 typedef AlterableGraphExtender Graph;
363 typedef _Base Parent;
365 typedef typename Parent::Node Node;
366 typedef typename Parent::Edge Edge;
368 /// The edge observer registry.
369 typedef AlterationNotifier<Edge> EdgeNotifier;
370 /// The node observer registry.
371 typedef AlterationNotifier<Node> NodeNotifier;
376 mutable EdgeNotifier edge_notifier;
378 mutable NodeNotifier node_notifier;
382 /// \brief Gives back the edge alteration notifier.
384 /// Gives back the edge alteration notifier.
385 EdgeNotifier& getNotifier(Edge) const {
386 return edge_notifier;
389 /// \brief Gives back the node alteration notifier.
391 /// Gives back the node alteration notifier.
392 NodeNotifier& getNotifier(Node) const {
393 return node_notifier;
396 ~AlterableGraphExtender() {
397 node_notifier.clear();
398 edge_notifier.clear();
404 template <typename _Base>
405 class AlterableEdgeSetExtender : public _Base {
408 typedef AlterableEdgeSetExtender Graph;
409 typedef _Base Parent;
411 typedef typename Parent::Edge Edge;
413 /// The edge observer registry.
414 typedef AlterationNotifier<Edge> EdgeNotifier;
418 mutable EdgeNotifier edge_notifier;
422 /// \brief Gives back the edge alteration notifier.
424 /// Gives back the edge alteration notifier.
425 EdgeNotifier& getNotifier(Edge) const {
426 return edge_notifier;
429 ~AlterableEdgeSetExtender() {
430 edge_notifier.clear();
435 /// \brief Class to extend an undirected graph with the functionality of
436 /// alteration observing.
440 /// \sa AlterableGraphExtender
442 /// \bug This should be done some other way. Possibilities: template
443 /// specialization (not very easy, if at all possible); some kind of
444 /// enable_if boost technique?
446 template <typename _Base>
447 class AlterableUGraphExtender
448 : public AlterableGraphExtender<_Base> {
451 typedef AlterableUGraphExtender Graph;
452 typedef AlterableGraphExtender<_Base> Parent;
454 typedef typename Parent::UEdge UEdge;
456 /// The edge observer registry.
457 typedef AlterationNotifier<UEdge> UEdgeNotifier;
461 mutable UEdgeNotifier u_edge_notifier;
465 using Parent::getNotifier;
466 UEdgeNotifier& getNotifier(UEdge) const {
467 return u_edge_notifier;
470 ~AlterableUGraphExtender() {
471 u_edge_notifier.clear();
475 template <typename _Base>
476 class AlterableUEdgeSetExtender
477 : public AlterableEdgeSetExtender<_Base> {
480 typedef AlterableUEdgeSetExtender Graph;
481 typedef AlterableEdgeSetExtender<_Base> Parent;
483 typedef typename Parent::UEdge UEdge;
485 typedef AlterationNotifier<UEdge> UEdgeNotifier;
489 mutable UEdgeNotifier u_edge_notifier;
493 using Parent::getNotifier;
494 UEdgeNotifier& getNotifier(UEdge) const {
495 return u_edge_notifier;
498 ~AlterableUEdgeSetExtender() {
499 u_edge_notifier.clear();
505 template <typename _Base>
506 class AlterableBpUGraphExtender : public _Base {
509 typedef _Base Parent;
510 typedef AlterableBpUGraphExtender Graph;
512 typedef typename Parent::Node Node;
513 typedef typename Parent::BNode BNode;
514 typedef typename Parent::ANode ANode;
515 typedef typename Parent::Edge Edge;
516 typedef typename Parent::UEdge UEdge;
519 typedef AlterationNotifier<Node> NodeNotifier;
520 typedef AlterationNotifier<BNode> BNodeNotifier;
521 typedef AlterationNotifier<ANode> ANodeNotifier;
522 typedef AlterationNotifier<Edge> EdgeNotifier;
523 typedef AlterationNotifier<UEdge> UEdgeNotifier;
527 mutable NodeNotifier nodeNotifier;
528 mutable BNodeNotifier bNodeNotifier;
529 mutable ANodeNotifier aNodeNotifier;
530 mutable EdgeNotifier edgeNotifier;
531 mutable UEdgeNotifier uEdgeNotifier;
535 NodeNotifier& getNotifier(Node) const {
539 BNodeNotifier& getNotifier(BNode) const {
540 return bNodeNotifier;
543 ANodeNotifier& getNotifier(ANode) const {
544 return aNodeNotifier;
547 EdgeNotifier& getNotifier(Edge) const {
551 UEdgeNotifier& getNotifier(UEdge) const {
552 return uEdgeNotifier;
555 ~AlterableBpUGraphExtender() {
556 nodeNotifier.clear();
557 bNodeNotifier.clear();
558 aNodeNotifier.clear();
559 edgeNotifier.clear();
560 uEdgeNotifier.clear();