next up previous contents
Next: STL Iterator Wrapper (STLNodeIt) Up: Graphs and Iterators Previous: Comparison Predicate (CompPred)

   
Observer Node Iterator (ObserverNodeIt)

Definition

An instance it of class ObserverNodeIt<Obs,Iter> is an observer iterator. Any method call of iterators will be ``observed'' by an internal object of class Obs. Class ObserverEdgeIt and ObserverAdjIt are defined analogously, i.e. can be used for edge iterators or adjacency iterators, respectively.

Precondition: The template parameter Iter must be a node iterator.

Creation

ObserverNodeIt<Obs,Iter> it; introduces a variable it of this class, not bound to an observer or iterator.

ObserverNodeIt<Obs,Iter>

it(Obs& obs, Iter base_it);
    introduces a variable it of this class bound to the observer obs and base_it. Precondition: Obs must have methods observe_constructor(), observe_forward(), observe_update(). These three methods may have arbitrary return types (incl. void).

   

Operations

void it.init(Obs obs, Iter base_it)
    initializes it, which is bound to obs and base_it afterwards. Precondition: it is not bound to an observer or iterator.

Obs& it.get_observer() returns a reference to the observer to which it is bound.

Example

First two simple observer classes. The first one is a dummy class, which ignores all notifications. The second one merely counts the number of calls to operator++ for all iterators that share the same observer object through copy construction or assignment (of course, a real implementation should apply some kind of reference counting or other garbage collection). In this example, the counter variable _count of class SimpleCountObserver will be initialized with the counter variable _count of class DummyObserver, i.e. the variable is created only once.

    template <class Iter>
    class DummyObserver {
      int* _count;
      public:
      DummyObserver() : _count(new int(0)) { }
      void notify_constructor(const Iter& ) { }
      void notify_forward(const Iter& ) { }
      void notify_update(const Iter& ) { }
      int  counter() const { return *_count; }
      int* counter_ptr() const { return _count; }
      bool operator==(const DummyObserver& D) const {
      return _count==D._count; }
    };
    
    template <class Iter, class Observer>
    class SimpleCountObserver {
      int*  _count;
      public:
      SimpleCountObserver() : _count(new int(0)) { }
      SimpleCountObserver(Observer& obs) :
      _count(obs.counter_ptr()) { }
      void notify_constructor(const Iter& ) { }
      void notify_forward(const Iter& ) { ++(*_count); }
      void notify_update(const Iter& ) { }
      int  counter() const {  return *_count; }
      int* counter_ptr() const { return _count; }
      bool operator==(const SimpleCountObserver& S) const {
      return _count==S._count; }
    };
Next an exemplary application, which counts the number of calls to operator++ of all adjacency iterator objects inside dummy_algorithm. Here the dummy observer class is used only as a ``Trojan horse,'' which carries the pointer to the counter without affecting the code of the algorithm.
    template<class Iter>
    bool break_condition (const Iter&) { ... }
    
    template<class ONodeIt, class OAdjIt>
    void  dummy_algorithm(ONodeIt& it, OAdjIt& it2) {
      while (it.valid()) {
        for (it2.update(it); it2.valid() && !break_condition(it2); ++it2)
        ++it;
      }
    }
    
    int write_count(graph& G) {
      typedef DummyObserver<NodeIt>                  DummyObs;
      typedef SimpleCountObserver<AdjIt,DummyObs>    CountObs;
      typedef ObserverNodeIt<DummyObs,NodeIt>        ONodeIt;
      typedef ObserverAdjIt<CountObs,AdjIt>          OAdjIt;
      
      DummyObs observer;
      ONodeIt   it(observer,NodeIt(G));
      CountObs  observer2(observer);
      OAdjIt    it2(observer2,AdjIt(G));
      dummy_algorithm(it,it2);
      return it2.get_observer().counter();
    }


next up previous contents
Next: STL Iterator Wrapper (STLNodeIt) Up: Graphs and Iterators Previous: Comparison Predicate (CompPred)
LEDA research project
1998-10-02