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

nodeiterator.h

Go to the documentation of this file.
00001 /***************************************************************************
00002 *  @file    nodeiterator.h
00003 *  @version 1.1
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 NODEITERATOR_H
00021 #define NODEITERATOR_H
00022 
00023 //#include <stack>
00024 #include <set>
00025 #include <list>
00026 //#include <iterator>
00027 #include "node.h"
00028 #include "nodeutil.h"
00029 
00030 namespace treecomp
00031 {
00032 
00033 /*
00034 template<class _TContent>
00035 class Node;
00036 */
00037 
00038 /*
00039 #if defined(__GNUC__) && defined(__STL_NO_NAMESPACES)
00040     #define BaseIterator forward_iterator<Node<_TContent>, ptrdiff_t >
00041 #else
00042     #define BaseIterator iterator<forward_iterator_tag, Node<_TContent> >
00043 #endif
00044 */
00045 
00046 /**
00047  * @interface NodeIterator
00048  * @ingroup nodeiterator
00049  *
00050  * @brief This iterator iterates in preorder over all nodes that belong to
00051  * a given node (have the same root).
00052  *
00053  * That means, it visits first a root
00054  * node and then its children.
00055  * It doesn't iterate
00056  * over subtree nodes. The default constructor makes a
00057  * 'past the end NodeIterator'.
00058  * It is the base class of all iterators and inherits from forward_iterator.
00059  * Template-parameter _TContent: see Node class.
00060  */
00061 template<class _Node, class _Ref=_Node&, class _Ptr=_Node*>
00062 class NodeIterator //: public BaseIterator
00063 {
00064 public:
00065     typedef typename NodeTraits<_Node>::_NonConstNode _NonConstNode;
00066 
00067     typedef NodeIterator<_Node> iterator;
00068     typedef NodeIterator<const _Node > const_iterator;
00069     typedef NodeIterator<_Node, _Ref,_Ptr> _Self;
00070 
00071 //  typedef bidirectional_iterator_tag iterator_category; // not yet supported
00072     typedef std::forward_iterator_tag iterator_category;
00073     typedef _Node value_type;
00074     typedef _Ptr pointer;
00075     typedef _Ref reference;
00076     typedef size_t size_type;
00077     typedef ptrdiff_t difference_type;
00078     
00079     /** The default constructor makes a 'past the end NodeIterator'. */
00080     NodeIterator() : m_currentNode(0), m_root(0), m_end(true) {}
00081     //NodeIterator(const _Self& it) {m_currentNode=it.m_currentNode; m_root=it.m_root;m_end=it.m_end;}
00082     //NodeIterator(const const_iterator& it) {m_currentNode=it.m_currentNode; m_root=it.m_root;}
00083 
00084     /** Construct a NodeIterator beginning at the given Node.
00085       * @param start The Node to start at */
00086     NodeIterator(_Node* start) { setStart(start); }
00087     virtual _Self* construct() const { return new _Self(); }
00088     virtual _Self* clone(_Node* start=0) const ;
00089     virtual ~NodeIterator() {}
00090 
00091     /**Dereference operator */
00092     virtual reference operator*() const { return *m_currentNode; }
00093     /**Dereference operator */
00094     virtual pointer operator->() const { return m_currentNode; }
00095     /** use like this: @code nodepointer=iter(); @endcode */
00096     virtual pointer operator()() const { return m_currentNode; }
00097     virtual bool operator==(const _Self& rhs);
00098     virtual bool operator!=(const _Self& rhs);
00099     virtual _Self operator++(int);
00100     virtual _Self& operator++();
00101     const bool& isEnd() const { return m_end; }
00102 
00103     virtual void setStart(_Node* start);
00104 
00105 protected:
00106     _Node* m_currentNode;
00107     _Node* m_root;
00108     std::list<_Node*> m_nodeList;
00109     std::set<_Node*> m_seenNodeSet;
00110 
00111     void setEnd(bool end=true) { m_end=end; }
00112     void addToNodeList(const std::list<_NonConstNode*>* values);
00113     
00114 private:
00115     bool m_end;
00116 };
00117 
00118 /**
00119  * @class PostOrderNodeIterator
00120  * @ingroup nodeiterator
00121  *
00122  * @brief This iterator iterates over all nodes in post order that belong to
00123  * a given node (have the same root) and are not fixed.
00124  *
00125  * \par It doesn't iterate over subtree nodes.
00126  * The default constructor makes a 'past the end VariableNodeIterator'.
00127  *
00128  * \note For pre and postorder iterators the
00129  * corresponding traversal classes are more
00130  * specialised and efficient.
00131  */
00132 template<class _Node, class _Ref=_Node&, class _Ptr=_Node*>
00133 class PostOrderNodeIterator : public NodeIterator<_Node,_Ref,_Ptr>
00134 {
00135 public:
00136     typedef PostOrderNodeIterator<_Node> iterator;
00137     typedef PostOrderNodeIterator<const _Node > const_iterator;
00138     typedef PostOrderNodeIterator<_Node, _Ref,_Ptr> _Self;
00139     typedef NodeIterator<_Node,_Ref,_Ptr> _Base;
00140     typedef typename NodeTraits<_Node>::_NonConstNode _NonConstNode;
00141 
00142     PostOrderNodeIterator() : _Base() {}
00143     /** Construct a PostOrderNodeIterator beginning at the given Node.
00144       * @param start The Node to start at */
00145     PostOrderNodeIterator(_Node* start) : _Base() { setStart(start); }
00146     virtual _Self* construct() const { return new _Self(); }
00147     virtual _Self* clone(_Node* start=0) const ;
00148     virtual ~PostOrderNodeIterator() {}
00149 
00150     virtual bool operator==(const _Self& rhs);
00151     virtual bool operator!=(const _Self& rhs);
00152     virtual _Self& operator++();
00153     
00154     virtual void setStart(_Node* start);
00155 };
00156 
00157 
00158 /**
00159  * @class VariableNodeIterator
00160  * @ingroup nodeiterator
00161  *
00162  * This iterator iterates over all nodes that belong to
00163  * a given node (have the same root) and are not fixed. It doesn't iterate
00164  * over subtree nodes.
00165  * The default constructor makes a 'past the end VariableNodeIterator'
00166  */
00167 template<class _Node, class _Ref=_Node&, class _Ptr=_Node*>
00168 class VariableNodeIterator : public NodeIterator<_Node,_Ref,_Ptr>
00169 {
00170 public:
00171     typedef VariableNodeIterator<_Node> iterator;
00172     typedef VariableNodeIterator<const _Node > const_iterator;
00173     typedef VariableNodeIterator<_Node, _Ref,_Ptr> _Self;
00174     typedef NodeIterator<_Node,_Ref,_Ptr> _Base;
00175 //  typedef typename NodeTraits<_Node>::_NonConstNode _NonConstNode;
00176     
00177     VariableNodeIterator() : _Base() {}
00178     /** Construct a VariableNodeIterator beginning at the given Node.
00179       * @param start The Node to start at */
00180     VariableNodeIterator(_Node* start) : _Base() { setStart(start); }
00181     virtual _Self* construct() const { return new _Self(); }
00182     virtual _Self* clone(_Node* start=0) const ;
00183     virtual ~VariableNodeIterator() {}
00184     virtual void setStart(_Node* start) { _Base::setStart(start); operator++(); }
00185 
00186     virtual bool operator==(const _Self& rhs);
00187     virtual bool operator!=(const _Self& rhs);
00188     virtual _Self& operator++();
00189 };
00190 
00191 
00192 /**
00193  * @class LeaveIterator
00194  * @ingroup nodeiterator
00195  *
00196  * @brief This iterator iterates over all leaves that belong to
00197  * a given node (have the same root).
00198  *
00199  * It doesn't iterate
00200  * over subtree nodes.
00201  * The default constructor makes a 'past the end LeaveIterator'.
00202  */
00203 
00204 template<class _Node, class _Ref=_Node&, class _Ptr=_Node*>
00205 class LeaveIterator : public NodeIterator<_Node,_Ref,_Ptr>
00206 {
00207 public: 
00208     typedef LeaveIterator<_Node> iterator;
00209     typedef LeaveIterator<const _Node > const_iterator;
00210     typedef LeaveIterator<_Node, _Ref,_Ptr> _Self;
00211     typedef NodeIterator<_Node,_Ref,_Ptr> _Base;
00212 //  typedef typename NodeTraits<_Node>::_NonConstNode _NonConstNode;
00213     
00214     LeaveIterator() : _Base() {}
00215     /** Construct a LeaveIterator beginning at the given Node.
00216       * @param start The Node to start at */
00217     LeaveIterator(_Node* start) : _Base() { setStart(start); }
00218     virtual _Self* construct() const { return new _Self(); }
00219     virtual _Self* clone(_Node* start=0) const;
00220     virtual ~LeaveIterator() {}
00221     virtual void setStart(_Node* start) { _Base::setStart(start); operator++(); }
00222 
00223     virtual bool operator==(const _Self& rhs);
00224     virtual bool operator!=(const _Self& rhs);
00225     virtual _Self& operator++();
00226 };
00227 
00228 
00229 /**
00230  * @class AllNodeIterator
00231  * @ingroup nodeiterator
00232  *
00233  * @brief This iterator iterates over all nodes that follow
00234  * a given node (with no respect to the root of node).
00235  *
00236  * The default constructor makes a 'past the end AllNodeIterator'
00237  */
00238 template<class _Node, class _Ref=_Node&, class _Ptr=_Node*>
00239 class AllNodeIterator : public NodeIterator<_Node,_Ref,_Ptr>
00240 {
00241 public:
00242     typedef AllNodeIterator<_Node> iterator;
00243     typedef AllNodeIterator<const _Node > const_iterator;
00244     typedef AllNodeIterator<_Node, _Ref,_Ptr> _Self;
00245     typedef NodeIterator<_Node,_Ref,_Ptr> _Base;
00246 //  typedef typename NodeTraits<_Node>::_NonConstNode _NonConstNode;
00247 
00248     AllNodeIterator() : _Base() {}
00249 //  AllNodeIterator(const _Self& it) : _Base(it) {}
00250 //  AllNodeIterator(const const_iterator& it) : _Base(it) {}
00251     AllNodeIterator(_Node* start) : _Base() { setStart(start); }
00252     virtual _Self* construct() const { return new _Self(); }
00253     virtual _Self* clone(_Node* start=0) const;
00254     virtual ~AllNodeIterator() {}
00255 
00256     virtual bool operator==(const _Self& rhs);
00257     virtual bool operator!=(const _Self& rhs);
00258     virtual _Self& operator++();
00259 };
00260 
00261 // =================== Template definition =================================
00262 
00263 // ====================
00264 // === NodeIterator ===
00265 // ====================
00266 
00267 
00268 
00269 /**
00270  * Copy constructor
00271  * @param start Node to start with (if not given make identical copy)
00272  */
00273 template<class _Node, class _Ref, class _Ptr>
00274 typename NodeIterator<_Node,_Ref,_Ptr>::_Self* 
00275 NodeIterator<_Node,_Ref,_Ptr>::clone(_Node* start) const
00276 {
00277     if (start)
00278         return new _Self(start);
00279     else
00280         return new _Self(*this);
00281 }
00282 
00283 /**
00284  * Set start node for next iteration
00285  * @param start The Node to start at
00286  */
00287 template<class _Node, class _Ref, class _Ptr>
00288 void 
00289 NodeIterator<_Node,_Ref,_Ptr>::setStart(_Node* start)
00290 {
00291     if (!start)
00292         return;
00293     m_seenNodeSet.clear();
00294     m_seenNodeSet.insert(start);
00295     m_nodeList.clear();
00296     m_end = false;
00297     m_currentNode = start;
00298     m_root = start;
00299 }
00300 
00301 
00302 /**
00303  * Equality operator
00304  * @warning Compares only 'past the end'
00305  */
00306 template<class _Node, class _Ref, class _Ptr>
00307 bool 
00308 NodeIterator<_Node,_Ref,_Ptr>::operator==(const _Self& rhs)
00309 {
00310     return (isEnd() && rhs.isEnd());
00311 }
00312 
00313 /**
00314  * Inequality operator
00315  * @warning Compares only 'past the end'
00316  */
00317 template<class _Node, class _Ref, class _Ptr>
00318 bool 
00319 NodeIterator<_Node,_Ref,_Ptr>::operator!=(const _Self& rhs)
00320 {
00321     return (!isEnd() || !rhs.isEnd());
00322 }
00323 
00324 /**
00325  * Prefix proceed operator
00326  */
00327 template<class _Node, class _Ref, class _Ptr>
00328 typename NodeIterator<_Node,_Ref,_Ptr>::_Self&
00329 NodeIterator<_Node,_Ref,_Ptr>::operator++()
00330 {
00331     addToNodeList( m_currentNode->getChildren() );
00332 
00333     if (!m_nodeList.empty())
00334     {
00335         m_currentNode = m_nodeList.back();
00336         m_nodeList.pop_back();
00337 
00338         // proceed if current node's root is not m_root
00339         if (m_currentNode->getRoot() != m_root)
00340             operator++();
00341     }
00342     else
00343         setEnd();
00344     return *this;
00345 }
00346 
00347 /**
00348  * Postfix proceed operator
00349  */
00350 template<class _Node, class _Ref, class _Ptr>
00351 typename NodeIterator<_Node,_Ref,_Ptr>::_Self
00352 NodeIterator<_Node,_Ref,_Ptr>::operator++(int n)
00353 {
00354 //  _Self temp = *this;
00355     int i;
00356     for (i=0;i<n;i++)
00357         this->operator++();
00358     return *this;
00359 }
00360 
00361 
00362 /**
00363  * Add Nodes from a NodeList to the list, if they aren't
00364  * already visited.
00365  * @param values NodeList to add to the list
00366  */
00367 template<class _Node, class _Ref, class _Ptr>
00368 void 
00369 NodeIterator<_Node,_Ref,_Ptr>::addToNodeList(const std::list<_NonConstNode*>* values)
00370 {
00371     typename std::list<_NonConstNode*>::const_reverse_iterator it = values->rbegin();
00372 
00373     _Node* currentValue;
00374     while(it != values->rend())
00375     {
00376         currentValue = *it;
00377         if(m_seenNodeSet.count(currentValue) == 0)
00378         {
00379             m_seenNodeSet.insert(currentValue);
00380             m_nodeList.push_back(currentValue);
00381         }
00382         ++it;
00383     }
00384 }
00385 
00386 // ============================
00387 // === PostOrderNodeIterator ===
00388 // ============================
00389 
00390 
00391 /**
00392  * Copy constructor
00393  * @param start Node to start with (if not given make identical copy)
00394  */
00395 template<class _Node, class _Ref, class _Ptr>
00396 typename PostOrderNodeIterator<_Node,_Ref,_Ptr>::_Self*
00397 PostOrderNodeIterator<_Node,_Ref,_Ptr>::clone(_Node* start) const
00398 {
00399     if (start)
00400         return new _Self(start);
00401     else
00402         return new _Self(*this);
00403 }
00404 
00405 /**
00406  * Equality operator
00407  * @warning Compares only 'past the end'
00408  */
00409 template<class _Node, class _Ref, class _Ptr>
00410 bool
00411 PostOrderNodeIterator<_Node,_Ref,_Ptr>::operator==(const _Self& rhs)
00412 {
00413     return (isEnd() && rhs.isEnd());
00414 }
00415 
00416 /**
00417  * Inequality operator
00418  * @warning Compares only 'past the end'
00419  */
00420 template<class _Node, class _Ref, class _Ptr>
00421 bool
00422 PostOrderNodeIterator<_Node,_Ref,_Ptr>::operator!=(const _Self& rhs)
00423 {
00424     return (!isEnd() || !rhs.isEnd());
00425 }
00426 
00427 
00428 template<class _Node, class _Ref, class _Ptr>
00429 void
00430 PostOrderNodeIterator<_Node,_Ref,_Ptr>::setStart(_Node* start)
00431 {
00432     _Base::setStart(start);
00433     
00434     // as long as nodes have children, step down to leftmost child
00435     while (m_currentNode->getChildren()->size()>0)
00436         m_currentNode = *(m_currentNode->getChildren()->begin());
00437     return;
00438 }
00439 
00440 
00441 /**
00442  * Prefix proceed operator
00443  */
00444 template<class _Node, class _Ref, class _Ptr>
00445 typename PostOrderNodeIterator<_Node,_Ref,_Ptr>::_Self&
00446 PostOrderNodeIterator<_Node,_Ref,_Ptr>::operator++()
00447 {   
00448     _Node* travelnode=0;
00449     const std::list<_NonConstNode*>* children=0;
00450 
00451     // we are ready
00452     if (m_currentNode==m_root)
00453     {
00454         setEnd();
00455         return *this;
00456     }
00457     
00458     // we cannot move right -> move up -> print parent
00459     travelnode=m_currentNode->getRightSibling();
00460     if (!travelnode)
00461     {
00462         if (!(m_currentNode=m_currentNode->getParent()))
00463         {   
00464             cerr << "Error in postorder algorithm";
00465             exit(-1);
00466         }
00467         return *this;
00468     }
00469     else
00470     {
00471         // move right worked -> check for children
00472         // as long as nodes have children, step down to leftmost child
00473         children = travelnode->getChildren();
00474         while (children->size()>0)
00475         {
00476             travelnode = *(children->begin());
00477             children = travelnode->getChildren();
00478         }
00479         m_currentNode = travelnode; // no more children
00480     }
00481     return *this;
00482 }
00483 
00484 
00485 // ============================
00486 // === VariableNodeIterator ===
00487 // ============================
00488 
00489 
00490 /**
00491  * Copy constructor
00492  * @param start Node to start with (if not given make identical copy)
00493  */
00494 template<class _Node, class _Ref, class _Ptr>
00495 typename VariableNodeIterator<_Node,_Ref,_Ptr>::_Self*
00496 VariableNodeIterator<_Node,_Ref,_Ptr>::clone(_Node* start) const
00497 {
00498     if (start)
00499         return new _Self(start);
00500     else
00501         return new _Self(*this);
00502 }
00503 
00504 /**
00505  * Equality operator
00506  * @warning Compares only 'past the end'
00507  */
00508 template<class _Node, class _Ref, class _Ptr>
00509 bool 
00510 VariableNodeIterator<_Node,_Ref,_Ptr>::operator==(const _Self& rhs)
00511 {
00512     return (isEnd() && rhs.isEnd());
00513 }
00514 
00515 /**
00516  * Inequality operator
00517  * @warning Compares only 'past the end'
00518  */
00519 template<class _Node, class _Ref, class _Ptr>
00520 bool 
00521 VariableNodeIterator<_Node,_Ref,_Ptr>::operator!=(const _Self& rhs)
00522 {
00523     return (!isEnd() || !rhs.isEnd());
00524 }
00525 
00526 
00527 /**
00528  * Prefix proceed operator
00529  */
00530 template<class _Node, class _Ref, class _Ptr>
00531 typename VariableNodeIterator<_Node,_Ref,_Ptr>::_Self&
00532 VariableNodeIterator<_Node,_Ref,_Ptr>::operator++()
00533 {
00534     addToNodeList(m_currentNode->getChildren());
00535 
00536     if (!m_nodeList.empty())
00537     {
00538         m_currentNode = m_nodeList.back();
00539         m_nodeList.pop_back();
00540 
00541         // proceed if current node is not child of root or current node is fixed
00542         if ((m_currentNode->getRoot() != m_root) || m_currentNode->isFixed())
00543             operator++();
00544     }
00545     else
00546         setEnd();
00547     return *this;
00548 }
00549 
00550 
00551 
00552 // =====================
00553 // === LeaveIterator ===
00554 // =====================
00555 
00556 
00557 /**
00558  * Copy constructor
00559  * @param start Node to start with (if not given make identical copy)
00560  */
00561 template<class _Node, class _Ref, class _Ptr>
00562 typename LeaveIterator<_Node,_Ref,_Ptr>::_Self*
00563 LeaveIterator<_Node,_Ref,_Ptr>::clone(_Node* start) const
00564 {
00565     if (start)
00566         return new _Self(start);
00567     else
00568         return new _Self(*this);
00569 }
00570 
00571 /**
00572  * Equality operator
00573  * @warning Compares only 'past the end'
00574  */
00575 template<class _Node, class _Ref, class _Ptr>
00576 bool 
00577 LeaveIterator<_Node,_Ref,_Ptr>::operator==(const _Self& rhs)
00578 {
00579     return (isEnd() && rhs.isEnd());
00580 }
00581 
00582 /**
00583  * Inequality operator
00584  * @warning Compares only 'past the end'
00585  */
00586 template<class _Node, class _Ref, class _Ptr>
00587 bool 
00588 LeaveIterator<_Node,_Ref,_Ptr>::operator!=(const _Self& rhs)
00589 {
00590     return (!isEnd() || !rhs.isEnd());
00591 }
00592 
00593 
00594 /**
00595  * Prefix proceed operator
00596  */
00597 template<class _Node, class _Ref, class _Ptr>
00598 typename LeaveIterator<_Node,_Ref,_Ptr>::_Self&
00599 LeaveIterator<_Node,_Ref,_Ptr>::operator++()
00600 {
00601     addToNodeList(m_currentNode->getChildren());
00602 
00603     if (!m_nodeList.empty())
00604     {
00605         m_currentNode = m_nodeList.back();
00606         m_nodeList.pop_back();
00607 
00608         // proceed if current node has children
00609         if (m_currentNode->getNumChildren() > 0)
00610             operator++();
00611     }
00612     else
00613         setEnd();
00614     return *this;
00615 }
00616 
00617 
00618 // =======================
00619 // === AllNodeIterator ===
00620 // =======================
00621 
00622 
00623 /**
00624  * Copy constructor
00625  * @param start Node to start with (if not given make identical copy)
00626  */
00627 template<class _Node, class _Ref, class _Ptr>
00628 typename AllNodeIterator<_Node,_Ref,_Ptr>::_Self*
00629 AllNodeIterator<_Node,_Ref,_Ptr>::clone(_Node* start) const
00630 {
00631     if (start)
00632         return new _Self(start);
00633     else
00634         return new _Self(*this);
00635 }
00636 
00637 /**
00638  * Equality operator
00639  * @warning Compares only 'past the end'
00640  */
00641 template<class _Node, class _Ref, class _Ptr>
00642 bool 
00643 AllNodeIterator<_Node,_Ref,_Ptr>::operator==(const _Self& rhs)
00644 {
00645     return (isEnd() && rhs.isEnd());
00646 }
00647 
00648 /**
00649  * Inequality operator
00650  * @warning Compares only 'past the end'
00651  */
00652 template<class _Node, class _Ref, class _Ptr>
00653 bool 
00654 AllNodeIterator<_Node,_Ref,_Ptr>::operator!=(const _Self& rhs)
00655 {
00656     return (!isEnd() || !rhs.isEnd());
00657 }
00658 
00659 
00660 /**
00661  * Prefix proceed operator
00662  */
00663 template<class _Node, class _Ref, class _Ptr>
00664 AllNodeIterator<_Node,_Ref,_Ptr>& 
00665 AllNodeIterator<_Node,_Ref,_Ptr>::operator++()
00666 {
00667     addToNodeList(m_currentNode->getChildren());
00668 
00669     if (!m_nodeList.empty())
00670     {
00671         m_currentNode = m_nodeList.back();
00672         m_nodeList.pop_back();
00673     }
00674     else
00675         setEnd();
00676     return *this;
00677 }
00678 
00679 
00680 } // namespace treecomp
00681 
00682 #endif //NODEITERATOR_H

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