COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/bits/alteration_notifier.h @ 1956:a055123339d5

Last change on this file since 1956:a055123339d5 was 1956:a055123339d5, checked in by Alpar Juttner, 18 years ago

Unified copyright notices

File size: 14.9 KB
RevLine 
[946]1/* -*- C++ -*-
2 *
[1956]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).
[946]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
[1946]25///\ingroup graphmapfactory
[946]26///\file
27///\brief Observer registry for graph alteration observers.
28
29namespace lemon {
30
[1910]31  /// \addtogroin graphmapfactory
[946]32  /// @{
33
[1414]34  /// \brief Registry class to register objects observes alterations in
35  /// the graph.
36  ///
[946]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
[1038]40  /// from the \ref AlterationNotifier::ObserverBase and override
[946]41  /// the virtual functions in that.
42  ///
43  /// The most important application of the alteration observing is the
[1414]44  /// dynamic map implementation.
[946]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>
[1038]52  class AlterationNotifier {
[946]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
[1204]68    /// about the container is built from an empty container or
[946]69    /// is cleared to an empty container.
70    ///
71    /// \author Balazs Dezso
72
73    class ObserverBase {
74    protected:
[1038]75      typedef AlterationNotifier Registry;
[946]76
[1038]77      friend class AlterationNotifier;
[946]78
[1414]79      /// \brief Default constructor.
80      ///
[946]81      /// Default constructor for ObserverBase.
82      ///
83      ObserverBase() : registry(0) {}
84
[1685]85      ObserverBase(const ObserverBase& copy) {
86        if (copy.attached()) {
87          copy.getRegistry()->attach(*this);
88        }
89      }
90       
[946]91      virtual ~ObserverBase() {}
92
[1414]93      /// \brief Attaches the observer into an AlterationNotifier.
94      ///
[1038]95      /// This member attaches the observer into an AlterationNotifier.
[946]96      ///
[1038]97      void attach(AlterationNotifier& r) {
[946]98        registry = &r;
99        registry->attach(*this);
100      }
101
[1414]102      /// \brief Detaches the observer into an AlterationNotifier.
103      ///
[1038]104      /// This member detaches the observer from an AlterationNotifier.
[946]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; }
[1685]122
[946]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       
[1414]139      virtual void add(const Item&) = 0;
[946]140
[1414]141      /// \brief The member function to notificate the observer about
[1718]142      /// more item is added to the container.
[1414]143      ///
[1718]144      /// The add() member function notificates the observer about more item
[1414]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      }
[946]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
[1718]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.
[1414]169      virtual void erase(const std::vector<Item>& items) {
170        for (int i = 0; i < (int)items.size(); ++i) {
[1701]171          erase(items[i]);
[1414]172        }
173      }
174
[946]175      /// \brief The member function to notificate the observer about the
[1204]176      /// container is built.
[946]177      ///
178      /// The build() member function notificates the observer about the
[1204]179      /// container is built from an empty container. It have to be
[946]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    ///
[1038]208    /// The default constructor of the AlterationNotifier.
[946]209    /// It creates an empty registry.
[1038]210    AlterationNotifier() {}
[946]211
[1038]212    /// Copy Constructor of the AlterationNotifier.
[946]213       
[1038]214    /// Copy constructor of the AlterationNotifier.
[946]215    /// It creates only an empty registry because the copiable
216    /// registry's observers have to be registered still into that registry.
[1039]217    AlterationNotifier(const AlterationNotifier&) {}
[946]218
219    /// Assign operator.
220               
[1038]221    /// Assign operator for the AlterationNotifier.
[1040]222    /// It makes the notifier only empty because the copiable
223    /// notifier's observers have to be registered still into that registry.
[1039]224    AlterationNotifier& operator=(const AlterationNotifier&) {
[946]225      typename Container::iterator it;
226      for (it = container.begin(); it != container.end(); ++it) {
227        (*it)->registry = 0;
228      }
229    }
230
231    /// Destructor.
232                               
[1038]233    /// Destructor of the AlterationNotifier.
[946]234    ///
[1038]235    ~AlterationNotifier() {
[946]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       
[1414]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.
[946]265    ///
[1414]266    void add(const Item& item) {
[946]267      typename Container::iterator it;
268      for (it = container.begin(); it != container.end(); ++it) {
[1414]269        (*it)->add(item);
[946]270      }
271    }   
272
[1414]273    /// \brief Notifies all the registered observers about more Item added to
274    /// the container.
275    ///
276    /// It notifies all the registered observers about more Item added to
277    /// the container.
278    ///
279    void add(const std::vector<Item>& items) {
280      typename Container::iterator it;
281      for (it = container.begin(); it != container.end(); ++it) {
282        (*it)->add(items);
283      }
284    }   
285
286    /// \brief Notifies all the registered observers about an Item erased from
287    /// the container.
288    ///
289    /// It notifies all the registered observers about an Item erased from
290    /// the container.
[946]291    ///
292    void erase(const Item& key) {
293      typename Container::iterator it;
294      for (it = container.begin(); it != container.end(); ++it) {
295        (*it)->erase(key);
296      }
297    }
[1414]298
299    /// \brief Notifies all the registered observers about more Item erased 
300    /// from the container.
301    ///
302    /// It notifies all the registered observers about more Item erased from
303    /// the container.
304    ///
305    void erase(const std::vector<Item>& items) {
306      typename Container::iterator it;
307      for (it = container.begin(); it != container.end(); ++it) {
308        (*it)->erase(items);
309      }
310    }
[946]311
[1414]312    /// \brief Notifies all the registered observers about the container is
313    /// built.
314    ///         
[1204]315    /// Notifies all the registered observers about the container is built
[946]316    /// from an empty container.
317    void build() {
318      typename Container::iterator it;
319      for (it = container.begin(); it != container.end(); ++it) {
320        (*it)->build();
321      }
322    }
323
324
[1414]325    /// \brief Notifies all the registered observers about all Items are
326    /// erased.
327    ///
[946]328    /// Notifies all the registered observers about all Items are erased
329    /// from the container.
330    void clear() {
331      typename Container::iterator it;
332      for (it = container.begin(); it != container.end(); ++it) {
333        (*it)->clear();
334      }
335    }
336  };
337
338
[962]339  /// \brief Class to extend a graph with the functionality of alteration
340  /// observing.
341  ///
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.
345  ///
346  /// \todo Document what "alteration observing" is. And probably find a
347  /// better (shorter) name.
[946]348  ///
349  /// \param _Base is the base class to extend.
350  ///
351  /// \pre _Base is conform to the BaseGraphComponent concept.
352  ///
[962]353  /// \post AlterableGraphExtender<_Base> is conform to the
354  /// AlterableGraphComponent concept.
[946]355  ///
356  /// \author Balazs Dezso
357
358  template <typename _Base>
359  class AlterableGraphExtender : public _Base {
360  public:
361
362    typedef AlterableGraphExtender Graph;
363    typedef _Base Parent;
364
365    typedef typename Parent::Node Node;
366    typedef typename Parent::Edge Edge;
367
[962]368    /// The edge observer registry.
[1039]369    typedef AlterationNotifier<Edge> EdgeNotifier;
[946]370    /// The node observer registry.
[1039]371    typedef AlterationNotifier<Node> NodeNotifier;
[946]372
373
374  protected:
375
[1040]376    mutable EdgeNotifier edge_notifier;
[946]377
[1040]378    mutable NodeNotifier node_notifier;
[946]379
380  public:
381
[1134]382    /// \brief Gives back the edge alteration notifier.
383    ///
384    /// Gives back the edge alteration notifier.
385    EdgeNotifier& getNotifier(Edge) const {
[1040]386      return edge_notifier;
[946]387    }
388
[1134]389    /// \brief Gives back the node alteration notifier.
390    ///
391    /// Gives back the node alteration notifier.
392    NodeNotifier& getNotifier(Node) const {
[1040]393      return node_notifier;
[946]394    }
395
396    ~AlterableGraphExtender() {
[1040]397      node_notifier.clear();
398      edge_notifier.clear();
[946]399    }
400   
401  };
402
[1842]403
404  template <typename _Base>
405  class AlterableEdgeSetExtender : public _Base {
406  public:
407
408    typedef AlterableEdgeSetExtender Graph;
409    typedef _Base Parent;
410
411    typedef typename Parent::Edge Edge;
412
413    /// The edge observer registry.
414    typedef AlterationNotifier<Edge> EdgeNotifier;
415
416  protected:
417
418    mutable EdgeNotifier edge_notifier;
419
420  public:
421
422    /// \brief Gives back the edge alteration notifier.
423    ///
424    /// Gives back the edge alteration notifier.
425    EdgeNotifier& getNotifier(Edge) const {
426      return edge_notifier;
427    }
428
429    ~AlterableEdgeSetExtender() {
430      edge_notifier.clear();
431    }
432   
433  };
434
[962]435  /// \brief Class to extend an undirected graph with the functionality of
436  /// alteration observing.
437  ///
438  /// \todo Document.
439  ///
440  /// \sa AlterableGraphExtender
441  ///
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?
445
446  template <typename _Base>
[1909]447  class AlterableUGraphExtender
[962]448    : public AlterableGraphExtender<_Base> {
449  public:
450
[1909]451    typedef AlterableUGraphExtender Graph;
[962]452    typedef AlterableGraphExtender<_Base> Parent;
453
[1909]454    typedef typename Parent::UEdge UEdge;
[962]455
456    /// The edge observer registry.
[1909]457    typedef AlterationNotifier<UEdge> UEdgeNotifier;
[962]458
459  protected:
460
[1909]461    mutable UEdgeNotifier u_edge_notifier;
[962]462
[1022]463  public:
464
[1038]465    using Parent::getNotifier;
[1909]466    UEdgeNotifier& getNotifier(UEdge) const {
467      return u_edge_notifier;
[962]468    }
469
[1909]470    ~AlterableUGraphExtender() {
471      u_edge_notifier.clear();
[962]472    }
473  };
[1820]474
[1842]475  template <typename _Base>
[1909]476  class AlterableUEdgeSetExtender
[1842]477    : public AlterableEdgeSetExtender<_Base> {
478  public:
479
[1909]480    typedef AlterableUEdgeSetExtender Graph;
[1842]481    typedef AlterableEdgeSetExtender<_Base> Parent;
482
[1909]483    typedef typename Parent::UEdge UEdge;
[1842]484
[1909]485    typedef AlterationNotifier<UEdge> UEdgeNotifier;
[1842]486
487  protected:
488
[1909]489    mutable UEdgeNotifier u_edge_notifier;
[1842]490
491  public:
492
493    using Parent::getNotifier;
[1909]494    UEdgeNotifier& getNotifier(UEdge) const {
495      return u_edge_notifier;
[1842]496    }
497
[1909]498    ~AlterableUEdgeSetExtender() {
499      u_edge_notifier.clear();
[1842]500    }
501  };
502
503
[1820]504
505  template <typename _Base>
[1910]506  class AlterableBpUGraphExtender : public _Base {
[1820]507  public:
508
509    typedef _Base Parent;
[1910]510    typedef AlterableBpUGraphExtender Graph;
[1820]511 
512    typedef typename Parent::Node Node;
[1910]513    typedef typename Parent::BNode BNode;
514    typedef typename Parent::ANode ANode;
[1820]515    typedef typename Parent::Edge Edge;
[1909]516    typedef typename Parent::UEdge UEdge;
[1820]517 
518 
519    typedef AlterationNotifier<Node> NodeNotifier;
[1910]520    typedef AlterationNotifier<BNode> BNodeNotifier;
521    typedef AlterationNotifier<ANode> ANodeNotifier;
[1820]522    typedef AlterationNotifier<Edge> EdgeNotifier;
[1909]523    typedef AlterationNotifier<UEdge> UEdgeNotifier;
[1820]524
525  protected:
526
527    mutable NodeNotifier nodeNotifier;
[1910]528    mutable BNodeNotifier bNodeNotifier;
529    mutable ANodeNotifier aNodeNotifier;
[1820]530    mutable EdgeNotifier edgeNotifier;
[1909]531    mutable UEdgeNotifier uEdgeNotifier;
[1820]532
533  public:
534
535    NodeNotifier& getNotifier(Node) const {
536      return nodeNotifier;
537    }
538
[1910]539    BNodeNotifier& getNotifier(BNode) const {
540      return bNodeNotifier;
[1820]541    }
542
[1910]543    ANodeNotifier& getNotifier(ANode) const {
544      return aNodeNotifier;
[1820]545    }
546
547    EdgeNotifier& getNotifier(Edge) const {
548      return edgeNotifier;
549    }
550
[1909]551    UEdgeNotifier& getNotifier(UEdge) const {
552      return uEdgeNotifier;
[1820]553    }
554
[1910]555    ~AlterableBpUGraphExtender() {
[1820]556      nodeNotifier.clear();
[1910]557      bNodeNotifier.clear();
558      aNodeNotifier.clear();
[1820]559      edgeNotifier.clear();
[1909]560      uEdgeNotifier.clear();
[1820]561    }
562
563  };
[946]564 
565/// @}
566 
567
568}
569
570#endif
Note: See TracBrowser for help on using the repository browser.