Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Compound Members  

nodevisitor.h

Go to the documentation of this file.
00001 /***************************************************************************
00002 *  @file    visitor.h
00003 *  @version 1.0
00004 *
00005 *  @author  Ingo Herwig, TU Darmstadt, FG Regelsystemtheorie und Robotik
00006 *  @author  Eva Brucherseifer, TU Darmstadt, FG Regelsystemtheorie und Robotik
00007 *  @date    2001
00008 *
00009 ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Library Public License as       *
00015  *   published by the Free Software Foundation; either version 2 of the    *
00016  *   License, or (at your option) any later version.                       *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #ifndef NODEVISITOR_H
00021 #define NODEVISITOR_H
00022 
00023 #include <vector>
00024 //#include <algorithm>
00025 #include "node.h"
00026 #include "nodeiterator.h"
00027 #include "nodeutil.h"
00028 #include "nodeoutputstrategy.h"
00029 
00030 
00031 namespace treecomp
00032 {
00033 
00034                   
00035 template<class _TContent>
00036 class Node;
00037 template<class _TContent>
00038 class NormalNode;
00039 template<class _TContent>
00040 class RootNode;
00041 
00042 template<class _TContent>
00043 class OutputStrategy;
00044 template<class _TContent>
00045 class NullOutputStrategy;
00046 
00047 
00048 // =======================
00049 // === NodeVisitorBase ===
00050 // =======================
00051 /**
00052  * @interface NodeVisitorBase
00053  * @ingroup nodevisitor
00054  *
00055  * @brief Visitors are used to extend the Node classes without changing their implementation ('visitor pattern')
00056  * NodeVisitor is the base class of all visitors.
00057  * Visitors use an iterator to traverse the tree. So the result depends on the given iteration algorithm.
00058  * If set to non-recursive they only visit one node. The default value is true, so the visitor works
00059  * recursively.
00060  */
00061 template<class _Node, class _NormalNode,    class _RootNode>
00062 class NodeVisitorBase
00063 {
00064 public: 
00065     typedef NodeVisitorBase<_Node,_NormalNode,_RootNode> _Self;
00066 
00067     explicit NodeVisitorBase() {}
00068     
00069 //  virtual _Self* construct() const = 0;
00070 //  virtual _Self* clone() const = 0;
00071     virtual ~NodeVisitorBase(){}
00072     
00073     virtual void visitNormalNode(_NormalNode* node) = 0;
00074     virtual void visitRootNode(_RootNode* node) = 0;
00075 };
00076 
00077 
00078 // ===================
00079 // === NodeVisitor ===
00080 // ===================
00081 /**
00082  * @interface NodeVisitor
00083  * @ingroup nodevisitor
00084  *
00085  * @brief Visitors are used to extend the Node classes without changing their implementation ('visitor pattern')
00086  * NodeVisitor is the base class of all visitors.
00087  * Visitors use an iterator to traverse the tree. So the result depends on the given iteration algorithm.
00088  * If set to non-recursive they only visit one node. The default value is true, so the visitor works
00089  * recursively
00090  */
00091 template<class _TIter,
00092     class _Node,
00093     class _NormalNode,
00094     class _RootNode>
00095 class NodeVisitor : public NodeVisitorBase<_Node, _NormalNode, _RootNode>
00096 {
00097 public:
00098     typedef NodeVisitor<_TIter,_Node,_NormalNode,_RootNode> _Self;
00099     typedef NodeVisitorBase<_Node,_NormalNode,_RootNode> _Base;
00100 //  typedef _TIter iterator_type;
00101 
00102     explicit NodeVisitor()
00103         : _Base(), m_start(0), m_iter(new _TIter), m_recursive(true)
00104         {}
00105         
00106     /** no copying allowed, use clone() instead */
00107     explicit NodeVisitor(const _Self& nv)
00108         : _Base(), m_start(nv.m_start), m_iter(nv.m_iter->clone()), m_recursive(nv.m_recursive)
00109         {}
00110     
00111 //  virtual _Self* construct() const {return new _Self(); }
00112 //  virtual _Self* clone() const { return new _Self(*this); }
00113     virtual ~NodeVisitor();
00114     
00115     /** Start function. Derived implementations MUST call the init method!  */
00116     virtual void operator()(_TIter& iter) = 0;
00117     virtual void operator()(_Node* node) { _TIter iter(node); this->operator()(iter); } 
00118 //  virtual void operator()(_Node& node) { _TIter iter(&node); this->operator()(iter); }
00119     virtual void visitNormalNode(_NormalNode* node) = 0;
00120     virtual void visitRootNode(_RootNode* node) = 0;
00121     /** 'True' the Visitor iterates over children too.
00122      *  'False' the Visitor only visits the start node */
00123     virtual void setRecursive(bool recursive) { m_recursive = recursive; }
00124     virtual bool isRecursive() const { return m_recursive; }
00125 
00126 protected:
00127     /** The visit iteration, should be called by start */
00128     virtual void iterate(NodeVisitorBase<_Node,_NormalNode,_RootNode>* self);
00129 //  virtual void init(NodeIterator<_TContent>* iter);
00130     virtual void init(_TIter& iter);
00131         
00132     _Node* m_start;
00133     //NodeIterator<_TContent>* m_iter;
00134     _TIter* m_iter; //!< local copy
00135     
00136 private:
00137     /** no assignment allowed, use clone() instead */
00138     _Self& operator=(const _Self& nv){return *this;}
00139     
00140     bool m_recursive;
00141 };
00142 
00143 
00144 
00145 // =====================
00146 // === OutputVisitor ===
00147 // =====================
00148 
00149 /**
00150  * @class OutputVisitor
00151  * @ingroup nodevisitor
00152  *
00153  * @brief OutputVisitor is used for output of the tree.
00154  * It uses an configurable OutputStrategy (see OutputStrategy),
00155  * 'DefaultOutputStrategy' if none is given.
00156  */
00157 template<class _TContent, class _TIter>
00158 class OutputVisitor
00159     : public NodeVisitor<typename _TIter::const_iterator,const Node<_TContent>,
00160         const NormalNode<_TContent>,const RootNode<_TContent> >
00161 {
00162 public:
00163     typedef OutputVisitor<_TContent,_TIter> _Self;
00164     typedef NodeVisitor<typename _TIter::const_iterator,
00165             const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >
00166         _Base;
00167     typedef OutputStrategy<_TContent> strategy_type;
00168 //  typedef typename _TIter::const_iterator iterator_type;
00169 
00170 //  OutputVisitor() : _Base(), m_outputStrategy(0) {}
00171     explicit OutputVisitor(strategy_type* os=0);
00172     virtual ~OutputVisitor() {}
00173     
00174     virtual _Self* construct() const { return new _Self; }
00175     virtual _Self* clone() const { return new _Self(*this); }
00176 
00177     virtual void operator()(const Node<_TContent>* node) { typename _TIter::const_iterator iter(node); this->operator()(iter); }
00178     /** start function */
00179     virtual void operator()(_TIter& iter);
00180     virtual void visitNormalNode(const NormalNode<_TContent>* node);
00181     virtual void visitRootNode(const RootNode<_TContent>* node);
00182     
00183     void setOutputStrategy(strategy_type* os);
00184     void setNullOutputStrategy();   
00185     virtual strategy_type* outputStrategy() { return m_outputStrategy; }
00186 
00187 protected:
00188     explicit OutputVisitor(const OutputVisitor& ov)
00189         : _Base(ov), m_outputStrategy(ov.m_outputStrategy) {}
00190         
00191     strategy_type* m_outputStrategy;
00192     NullOutputStrategy<_TContent> m_nulloutputstrategy;
00193     
00194 private:
00195     virtual OutputVisitor& operator=(const OutputVisitor&) {return *this;}
00196 };
00197 
00198 
00199 
00200 // ======================
00201 // === CollectVisitor ===
00202 // ======================
00203 /**
00204  * @class CollectVisitor
00205  * @ingroup nodevisitor
00206  *
00207  * @brief This visitor collects all nodes into a vector which is provided through 'getList()'.
00208  */
00209 template<class _TContent, class _TIter, class _TContainer=std::vector<Node<_TContent>*> >
00210 class CollectVisitor
00211     : public NodeVisitor<_TIter, Node<_TContent>,   NormalNode<_TContent>, RootNode<_TContent> >
00212 {
00213 public:
00214     typedef CollectVisitor<_TContent,_TIter,_TContainer> _Self;
00215     typedef NodeVisitor<_TIter,Node<_TContent>, NormalNode<_TContent>, RootNode<_TContent> >
00216         _Base;
00217 //  typedef _TIter iterator_type;
00218 
00219     explicit CollectVisitor() : _Base() {}
00220     virtual _Self* construct() const { return new _Self(); }
00221     virtual _Self* clone() const { return new _Self(*this); }
00222 
00223     virtual void operator()(_TIter& iter);
00224     virtual void visitNormalNode(NormalNode<_TContent>* node);
00225     virtual void visitRootNode(RootNode<_TContent>* node);
00226 
00227     virtual _TContainer getCollected() { return m_container; }
00228 
00229 protected:
00230     explicit CollectVisitor(const CollectVisitor& cv)
00231         : _Base(cv) {}
00232     void addNode(Node<_TContent>* node);
00233     _TContainer m_container;
00234 private:
00235     virtual CollectVisitor& operator=(const CollectVisitor&) {return *this;}
00236 };
00237 
00238 
00239 
00240 // ====================
00241 // === DepthVisitor ===
00242 // ====================
00243 /**
00244  * @class DepthVisitor
00245  * @ingroup nodevisitor
00246  *
00247  * @brief This visitor measures the maximum depth of the tree, which is the distance from the given node
00248  * to the farest leave. The distance is provided through 'getDepth()'.
00249  */
00250 template<class _TContent, class _TIter>
00251 class DepthVisitor
00252     : public NodeVisitor<typename _TIter::const_iterator,const Node<_TContent>,
00253         const NormalNode<_TContent>,const RootNode<_TContent> >
00254 {
00255 public:
00256     typedef DepthVisitor<_TContent,_TIter> _Self;
00257     typedef NodeVisitor<typename _TIter::const_iterator,
00258             const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >
00259         _Base;
00260 //  typedef typename _TIter::const_iterator iterator_type;
00261 
00262     explicit DepthVisitor()
00263         : _Base(), m_curDepth(0), m_maxDepth(0), m_curParent(0), m_isLeave(false)
00264         {}
00265 
00266     virtual _Self* construct() const { return new _Self(); }
00267     virtual _Self* clone() const { return new _Self(*this); }
00268 
00269     virtual void operator()(_TIter& iter);
00270     virtual void visitNormalNode(const NormalNode<_TContent>* node);
00271     virtual void visitRootNode(const RootNode<_TContent>* node);
00272 
00273     virtual int getDepth() { return m_maxDepth; }
00274 
00275 protected:
00276     explicit DepthVisitor(const DepthVisitor& cv)
00277         : _Base(cv) {}
00278     void measure(const Node<_TContent>* node);
00279     int m_curDepth;
00280     int m_maxDepth;
00281     const Node<_TContent>* m_curParent;
00282     bool m_isLeave;
00283 private:
00284     virtual DepthVisitor& operator=(const DepthVisitor&) {return *this;}
00285 };
00286 
00287 
00288 // =================== Template definition =================================
00289 
00290 // ===================
00291 // === Nodevisitor ===
00292 // ===================
00293 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00294 void
00295 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::iterate(
00296     NodeVisitorBase<_Node,_NormalNode,_RootNode>* self)
00297 {
00298     _Node* node=0;
00299     if (m_recursive && m_iter)
00300         while(!m_iter->isEnd())
00301         {
00302             node = &(m_iter->operator*());
00303             assert(node!=0);
00304             node->acceptVisitor(self);
00305 //          node->acceptVisitor(this);
00306             m_iter->operator++();
00307         }
00308     else
00309     {
00310         assert(m_start!=0);
00311         m_start->acceptVisitor(self);
00312 //      m_start->acceptVisitor(this);
00313     }
00314 }
00315 
00316 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00317 //void NodeVisitor<_TContent>::init(NodeIterator<_TContent>* iter)
00318 void
00319 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::init(_TIter& iter)
00320 {
00321 
00322     if (m_iter)
00323     {
00324         delete m_iter;
00325         m_iter=0;
00326     }
00327     m_iter = new _TIter(iter);
00328     m_start = &(m_iter->operator*());
00329     assert(m_start!=0);
00330 }
00331 
00332 /**
00333  * Start the output process
00334  * @param node The Node to start with
00335  */
00336  /*
00337 template<class _TContent, class _TIter, class _Node, class _NormalNode, class _RootNode>
00338 void NodeVisitor<_TContent,_TIter>::start(_Node* node)
00339 {
00340     _TIter iter(node);
00341     start(iter);
00342 }
00343 
00344 */
00345 
00346 template<class _TIter, class _Node, class _NormalNode, class _RootNode>
00347 NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>::~NodeVisitor<_TIter,_Node,_NormalNode,_RootNode>()
00348 {
00349     if (m_iter)
00350         delete m_iter;
00351 }
00352 
00353 
00354 
00355 
00356 // =====================
00357 // === OutputVisitor ===
00358 // =====================
00359 /**
00360  * Constructor
00361  * If no outputstrategy is given the visitor uses NullOutputStrategy
00362  * that writes to stdout.
00363  * @param os The OutputStrategy to use
00364  */
00365 template<class _TContent, class _TIter>
00366 OutputVisitor<_TContent,_TIter>::OutputVisitor(strategy_type* os)
00367     : _Base(), m_nulloutputstrategy(&cout)
00368 {
00369     if (os == 0)
00370         m_outputStrategy = &m_nulloutputstrategy;
00371     else
00372         m_outputStrategy = os;
00373     assert(m_outputStrategy!=0);
00374 }
00375 
00376 
00377 
00378 /**
00379  * Start the output process
00380  * @param iter The NodeIterator that iterates over all nodes to visit
00381  */
00382 template<class _TContent, class _TIter>
00383 void OutputVisitor<_TContent,_TIter>::operator()(_TIter& iter)
00384 {
00385     init(iter);
00386     assert(m_outputStrategy!=0);
00387     m_outputStrategy->writeHeader();
00388     iterate(this);
00389     m_outputStrategy->writeFooter();
00390 }
00391 
00392 
00393 /**
00394  * Take a NormalNode and output its content
00395  * @param node The NormalNode to visit
00396  */
00397 template<class _TContent, class _TIter>
00398 void OutputVisitor<_TContent,_TIter>::visitNormalNode(const NormalNode<_TContent>* node)
00399 {
00400     assert(m_outputStrategy!=0);
00401     m_outputStrategy->writeNormalNode(node);
00402 }
00403 
00404 /**
00405  * Take a RootNode and output its content
00406  * @param node The RootNode to visit
00407  */
00408 template<class _TContent, class _TIter>
00409 void OutputVisitor<_TContent,_TIter>::visitRootNode(const RootNode<_TContent>* node)
00410 {
00411     assert(m_outputStrategy!=0);
00412     m_outputStrategy->writeRootNode(node);
00413 }
00414 
00415 /**
00416  * Set the OutputStrategy for the node content output
00417  * @param os The OutputStrategy to use
00418  */
00419 template<class _TContent, class _TIter>
00420 void OutputVisitor<_TContent,_TIter>::setOutputStrategy(strategy_type* os)
00421 {
00422     if (os)
00423         m_outputStrategy = os;
00424     else
00425         m_outputStrategy = &m_nulloutputstrategy;
00426     assert(m_outputStrategy!=0);
00427 }
00428 
00429 /**
00430  * Reset the OutputStrategy to a NullOutputStrategy
00431  */
00432 template<class _TContent, class _TIter>
00433 void OutputVisitor<_TContent,_TIter>::setNullOutputStrategy()
00434 {
00435 
00436     setOutputStrategy(0);
00437     assert(m_outputStrategy->isNull()==true);
00438 }
00439 
00440 // ======================
00441 // === CollectVisitor ===
00442 // ======================
00443 
00444 
00445 /**
00446  * Start the collection process
00447  * @param iter The NodeIterator that iterates over all nodes to visit
00448  */
00449 template<class _TContent, class _TIter, class _TContainer>
00450 void CollectVisitor<_TContent,_TIter,_TContainer>::operator()(_TIter& iter)
00451 {
00452     init(iter);
00453     m_container.clear();
00454     iterate(this);
00455 }
00456 
00457 /**
00458  * Take a NormalNode and put it in the list
00459  * @param node The NormalNode to visit
00460  */
00461 template<class _TContent, class _TIter, class _TContainer>
00462 void CollectVisitor<_TContent,_TIter,_TContainer>::visitNormalNode(NormalNode<_TContent>* node)
00463 {
00464     addNode(node);
00465 }
00466 
00467 /**
00468  * Take a RootNode and put its subtree in the list
00469  * @param node The RootNode to visit
00470  */
00471 template<class _TContent, class _TIter, class _TContainer>
00472 void CollectVisitor<_TContent,_TIter,_TContainer>::visitRootNode(RootNode<_TContent>* node)
00473 {
00474     addNode(node);
00475 }
00476 
00477 /**
00478  * Take a Node and put it in the list
00479  * @param node The Node to add
00480  */
00481 template<class _TContent, class _TIter, class _TContainer>
00482 void CollectVisitor<_TContent,_TIter,_TContainer>::addNode(Node<_TContent>* node)
00483 {
00484     m_container.push_back(node);
00485 }
00486 
00487 
00488 
00489 // ====================
00490 // === DepthVisitor ===
00491 // ====================
00492 
00493 
00494 /**
00495  * Start the measurement process
00496  * @param iter The NodeIterator that iterates over all nodes to visit
00497  */
00498 template<class _TContent, class _TIter>
00499 //void DepthVisitor<_TContent,_TIter>::start(NodeIterator<_TContent>* iter)
00500 void DepthVisitor<_TContent,_TIter>::operator()(_TIter& iter)
00501 {
00502     init(iter);
00503     m_curDepth = 1;
00504     m_maxDepth = 1;
00505     m_isLeave = false;
00506     m_curParent = 0;
00507 
00508     iterate(this);
00509 }
00510 
00511 /**
00512  * Take a NormalNode and calculate depth
00513  * @param node The NormalNode to visit
00514  */
00515 template<class _TContent, class _TIter>
00516 void DepthVisitor<_TContent,_TIter>::visitNormalNode(const NormalNode<_TContent>* node)
00517 {
00518     measure(node);
00519 }
00520 
00521 /**
00522  * Take a RootNode and calculate depth
00523  * @param node The RootNode to visit
00524  */
00525 template<class _TContent, class _TIter>
00526 void DepthVisitor<_TContent,_TIter>::visitRootNode(const RootNode<_TContent>* node)
00527 {
00528     measure(node);
00529 }
00530 
00531 /**
00532  * Take a Node and calculate depth
00533  * @param node The Node
00534  */
00535 template<class _TContent, class _TIter>
00536 void DepthVisitor<_TContent,_TIter>::measure(const Node<_TContent>* node)
00537 {
00538     if (node->getParent() != m_curParent)
00539     {
00540         // changed depth
00541         if (!m_isLeave)
00542         {
00543             // former node was no leave
00544             // so we descended one step
00545             ++m_curDepth;
00546         }
00547         else
00548         {
00549             // former node was leave
00550             // so we ascended one step
00551             --m_curDepth;
00552         }
00553         if (m_curDepth > m_maxDepth)
00554             m_maxDepth = m_curDepth;
00555         m_curParent = node->getParent();
00556     }
00557     if (node->getNumChildren())
00558         m_isLeave = false;
00559     else
00560         m_isLeave = true;
00561 }
00562 
00563 } // namespace treecomp
00564 
00565 #endif //NODEVISITOR_H

Generated on Mon Jan 6 12:02:09 2003 for TreeComp by doxygen1.2.17