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

node.h

Go to the documentation of this file.
00001 /***************************************************************************
00002 *  @file    node.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 
00021 
00022 #ifndef NODE_H
00023 #define NODE_H
00024 
00025 #include <list>
00026 #include <vector>
00027 #include <string>
00028 #include <map>
00029 
00030 #include <cassert>
00031 #include <algorithm>
00032 #include "nodevisitor.h"
00033 #include "nodeiterator.h"
00034 
00035 
00036 namespace treecomp
00037 {
00038 
00039 
00040 template<class _TContent>
00041 class Node;
00042 
00043 template<class _TContent>
00044 class NormalNode;
00045 
00046 template<class _TContent>
00047 class RootNode;
00048 
00049 /*
00050 template<   class _Node,    class _NormalNode, class _RootNode  >
00051 class NodeVisitorBase;
00052 
00053 template<class _TContent, class _TIter>
00054 class DepthVisitor;
00055 */
00056 
00057 // ============
00058 // === Node ===
00059 // ============
00060 /**
00061  * @interface Node
00062  * @ingroup node
00063  *
00064  * @brief This class provides the basic interface to the node-classes.
00065  *
00066  * Together with NormalNode and RootNode it implements the 'composite pattern'
00067  * in an extended way, which means that any node could be a leave.
00068  *
00069  * RootNodes are used as the root of a tree. Trees constructed in this way are recognized as a unit after insertion
00070  * into another tree.
00071  * NormalNodes are the basic parts of the tree.
00072  *
00073  * Applicationspecific content of the node is added by the template-parameter _TContent (which must have a public constructor,
00074  * destructor and copy-constructor).
00075  *
00076  * For copying trees use the function cloneTree(), which gives back a pointer to the copied tree.
00077  * The assignement operator is only the default version and should _never be used_. It only makes a copy of the data in the
00078  * copied class, but doesn't copy, what the pointer point to.
00079  * The Copy Contructor is made protected, so that it cannot be used.
00080  */
00081 template<class _TContent>
00082 class Node
00083 {
00084 public:
00085     // Node types
00086     typedef _TContent                   value_type;
00087     typedef value_type&             reference;
00088     typedef const value_type&       const_reference;
00089     typedef value_type*             pointer;
00090     typedef const value_type*       const_pointer;
00091     
00092     typedef NodeIterator<Node<value_type> > iterator;
00093     typedef NodeIterator<const Node<value_type> >    const_iterator;
00094     typedef AllNodeIterator<Node<value_type> >  all_iterator;   
00095     typedef AllNodeIterator<const Node<value_type> > const_all_iterator;    
00096     typedef PostOrderNodeIterator<Node<value_type> >    post_iterator;
00097     typedef PostOrderNodeIterator<const Node<value_type> > const_post_iterator;
00098     typedef VariableNodeIterator<Node<value_type> > var_iterator;   
00099     typedef VariableNodeIterator<const Node<value_type> > const_var_iterator;   
00100     typedef LeaveIterator<Node<value_type> > leave_iterator;    
00101     typedef LeaveIterator<const Node<value_type> > const_leave_iterator;    
00102     typedef size_t                              size_type;
00103     typedef ptrdiff_t                           difference_type;
00104     typedef std::reverse_iterator<iterator> reverse_iterator;
00105     typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00106     
00107     friend class NormalNode<_TContent>;
00108     friend class RootNode<_TContent>;
00109 
00110     explicit Node();
00111     explicit Node(const Node<_TContent>& node);
00112     explicit Node(const _TContent& content);
00113     virtual ~Node();
00114 
00115     virtual Node* construct() const = 0;
00116     virtual Node* cloneTree() const = 0;
00117     virtual Node* cloneNode() const = 0;
00118 
00119     /** Get the parent of this node. */
00120     virtual Node<_TContent>* getParent() { return m_parent; }
00121     virtual const Node<_TContent>* getParent() const { return m_parent; }
00122     /** Get the enclosing (sub-)trees root. */
00123     virtual Node<_TContent>* getRoot() { return m_root; }
00124     virtual const Node<_TContent>* getRoot() const { return m_root; }
00125     /** Get the left neighbor (or sister) of this node. */
00126     virtual Node<_TContent>* getLeftSibling() { return m_left_sibling; }
00127     virtual const Node<_TContent>* getLeftSibling() const { return m_left_sibling; }
00128     /** Get the right neighbor (or sister) of this node. */
00129     virtual Node<_TContent>* getRightSibling() { return m_right_sibling; }
00130     virtual const Node<_TContent>* getRightSibling() const { return m_right_sibling; }
00131     /** Get a list of children of this node. */
00132     virtual const std::list<Node<_TContent>*>* getChildren() const { return &m_children; }
00133     /** Get a list of leaves of this node. The list differs from the list
00134      * obtained by 'getChildren()' only if the node is root of a (sub-)
00135      * tree (= RootNode). */
00136     virtual const std::list<Node*>* getLeaves() const { return &m_children; }
00137     /** Get the number of direct children of this node. */
00138     virtual size_type getNumChildren() const { return m_children.size(); }
00139     /** Get the number of descendants of this node. The number differs from the number
00140      * obtained by 'getNumChildren()' only if the node is root of a (sub-)
00141      * tree (= RootNode). */
00142     virtual size_type getNumDescendants() const { return m_children.size(); }
00143     /** Get the maximal depth of the tree. */
00144     virtual int getDepth() const;
00145     /** Get the name of the node. */
00146     virtual std::string getName() const { return m_name; }
00147     /** Return fixed state */
00148     virtual bool isFixed() const { return m_fixed; }
00149 
00150     /** Update the list of leaves of this node
00151      * Does nothing for NormalNodes */
00152     virtual void recalcLeaves() {}
00153     /** Make the node fixed. Protect from deleting.
00154      *  @parem b True/False */
00155     virtual void setFixed(bool b) { m_fixed = b; }
00156     /** Set the name of the node. */
00157     virtual void setName(std::string name) { m_name = name; }
00158 
00159     /** Get a STL conform iterator to traverse the tree structure
00160         * beginning with this node (nodes of subtrees n o t included). */
00161     virtual iterator begin() { return iterator(this); }
00162     virtual const_iterator begin() const { return const_iterator(this); }
00163     /** Get the 'past the end' iterator */
00164     virtual iterator end() { return iterator();}
00165     virtual const_iterator end() const { return const_iterator();}
00166 
00167     /** Get an STL conform iterator to traverse the tree structure
00168      * beginning with this node (nodes of subtrees included). */
00169     virtual all_iterator beginAll() { return this; }
00170     virtual const_all_iterator beginAll() const { return this; }
00171     /** don't have a glue why the compiler doesn't pick the right const function, so
00172        here is an explicit call to get the const iterator*/
00173     virtual const_all_iterator beginAllConst() const { return this; }
00174     /** Get the 'past the end' iterator */
00175     virtual all_iterator endAll() { return all_iterator(); }
00176     virtual const_all_iterator endAll() const { return const_all_iterator(); }
00177 
00178     virtual bool addChildFront(Node* node);
00179     virtual bool addChildBack(Node* node);
00180     virtual bool addChild(Node* node);
00181     virtual bool addChild(Node* node, unsigned int index);
00182     virtual bool addChild(Node* node, typename std::list<Node*>::iterator& iter);
00183     virtual std::list<Node*> deleteChild(Node* node);
00184     virtual bool cutChild(Node* node);
00185     
00186     virtual void acceptVisitor(
00187         NodeVisitorBase<Node<_TContent>,NormalNode<_TContent>,RootNode<_TContent> >*
00188         visitor) = 0;
00189     virtual void acceptVisitor(
00190         NodeVisitorBase<const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >*
00191         visitor) const = 0;
00192 
00193     virtual void reduce();
00194 
00195     virtual pointer getContent() { return m_content; }
00196     virtual const_pointer getContent() const { return m_content; }
00197     
00198     /** Return true is the node is a RootNode
00199      *  This method is nescessary to distinguisch normal and super nodes inside node */
00200     virtual bool isRootNode() const { return false; }
00201 
00202 protected:  
00203     typedef std::map<const Node<_TContent>*, Node<_TContent>*> OldNewMap;
00204 
00205     virtual Node* copy(OldNewMap& nodeMap) const = 0;
00206     virtual void linkSiblings();
00207     virtual void setParent(Node* node);
00208     virtual void deleteParent();
00209     virtual void disconnectChildren();
00210     /** Set true to make the RootNode a unit in the enclosing tree
00211      * Does nothing for NormalNodes */
00212     virtual void setProtected(bool) {}
00213     /** Returns protection state */
00214     virtual bool isProtected() const { return m_protected; }
00215     virtual bool isInner() const;
00216 
00217     //! tree layout
00218     Node* m_parent;
00219     //! tree layout
00220     Node* m_root;
00221     //! tree layout
00222     Node* m_right_sibling;
00223     //! tree layout
00224     Node* m_left_sibling;
00225     //! tree layout
00226     std::list<Node<_TContent>*> m_children;
00227 
00228     //! node configuration
00229     _TContent* m_content;
00230     //! node configuration
00231     bool m_protected;   
00232     //! node configuration : if m_fixed is true, connection to parent node cannot be removed
00233     bool m_fixed;
00234     //! node configuration
00235     std::string m_name;
00236 
00237     /** this iterator points after every delete action
00238      * to the child in front of which was deleted
00239      * so its possible to use insert to repair  */
00240     typename std::list<Node*>::iterator m_repairIter;
00241 };
00242 
00243 
00244 
00245 // ==================
00246 // === NormalNode ===
00247 // ==================
00248 /**
00249  * @class NormalNode
00250  * @ingroup node
00251  *
00252  * This class is the basic part of the tree (see Node class).
00253  */
00254 template<class _TContent>
00255 class NormalNode : public Node<_TContent>
00256 {
00257 public:
00258     // Node types
00259 /*
00260     typedef NodeIterator<_TContent>     iterator;
00261     typedef const NodeIterator<_TContent>       const_iterator;
00262     typedef AllNodeIterator<_TContent>  alliterator;    
00263 */
00264     typedef size_t                              size_type;
00265     typedef ptrdiff_t                           difference_type;
00266     typedef Node<_TContent>&                reference;
00267     typedef const Node<_TContent>&      const_reference;
00268     typedef _TContent                           value_type;
00269     typedef Node<_TContent>*                pointer;
00270     typedef const Node<_TContent>*      const_pointer;
00271 //  typedef std::reverse_iterator<iterator> reverse_iterator;
00272 //  typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00273     
00274 //  NormalNode();
00275     virtual ~NormalNode() {}
00276         
00277     /** virtual default constructor */
00278     virtual NormalNode<_TContent>* construct() const { return new NormalNode<_TContent>;}
00279     virtual NormalNode<_TContent>* cloneTree() const;
00280     virtual NormalNode<_TContent>* cloneNode() const;
00281 
00282     virtual void acceptVisitor(
00283         NodeVisitorBase<Node<_TContent>,NormalNode<_TContent>,RootNode<_TContent> >*
00284         visitor);
00285     virtual void acceptVisitor(
00286         NodeVisitorBase<const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >*
00287         visitor) const;
00288 
00289 protected:  
00290     typedef std::map<const Node<_TContent>*, Node<_TContent>*> OldNewMap;
00291     virtual Node<_TContent>* copy(OldNewMap& nodeMap) const;
00292     
00293 private:
00294     /** use cloneTree() or cloneNode() instead */
00295     //NormalNode(const NormalNode& node) {}
00296     //NormalNode& operator=(const NormalNode& node) {return *this;}
00297 };
00298 
00299 
00300 // =================
00301 // === RootNode ===
00302 // =================
00303 /**
00304  * @class RootNode
00305  * @ingroup node
00306  *
00307  * This class is the root class of the tree (see Node class).
00308  */
00309 template<class _TContent>
00310 class RootNode : public Node<_TContent>
00311 {
00312 public:
00313     // Node types
00314   //typedef NodeIterator<_Tp,_Tp&,_Tp*>             iterator;
00315   //typedef NodeIterator<_Tp,const _Tp&,const _Tp*> const_iterator;
00316 /*
00317     typedef NodeIterator<_TContent>     iterator;
00318     typedef AllNodeIterator<_TContent>  alliterator;    
00319 */
00320     typedef size_t                              size_type;
00321     typedef ptrdiff_t                           difference_type;
00322     typedef Node<_TContent>&                reference;
00323     typedef const Node<_TContent>&      const_reference;
00324     typedef _TContent                           value_type;
00325     typedef Node<_TContent>*                pointer;
00326     typedef const Node<_TContent>*      const_pointer;
00327 //  typedef std::reverse_iterator<iterator> reverse_iterator;
00328 //  typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
00329     
00330     RootNode();
00331     /** virtual default constructor */
00332     virtual RootNode<_TContent>* construct() const { return new RootNode<_TContent>;}
00333     virtual RootNode<_TContent>* cloneTree() const;
00334     virtual RootNode<_TContent>* cloneNode() const;
00335     //virtual ~RootNode() {}
00336 
00337     virtual const std::list<Node<_TContent>*>* getLeaves() const { return &m_leaves; }
00338     virtual size_type getNumDescendants() const;
00339     virtual void recalcLeaves();
00340     virtual void acceptVisitor(
00341         NodeVisitorBase<Node<_TContent>,NormalNode<_TContent>,RootNode<_TContent> >*
00342         visitor);
00343     virtual void acceptVisitor(
00344         NodeVisitorBase<const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >*
00345         visitor) const;
00346     virtual bool isRootNode() const { return true; }
00347 
00348 protected:
00349     typedef std::map<const Node<_TContent>*, Node<_TContent>*> OldNewMap;
00350     virtual Node<_TContent>* copy(OldNewMap& nodeMap) const;
00351 
00352     virtual void deleteParent();
00353     virtual void setProtected(bool b);
00354 
00355     std::list<Node<_TContent>*> m_leaves;
00356 private:
00357     /** use cloneTree() or cloneNode() instead */
00358     //RootNode(const RootNode& node) {}
00359     //RootNode& operator=(const RootNode& node) {return *this;} 
00360 };
00361 
00362 // =================== Template definition =================================
00363 
00364 // ============
00365 // === Node ===
00366 // ============
00367 
00368 
00369 template<class _TContent>
00370 Node<_TContent>::Node()
00371     :   m_parent(0), m_root(0),
00372         m_right_sibling(0), m_left_sibling(0),
00373         m_content(0),
00374         m_protected(false), m_fixed(false),
00375         m_name("no name"), m_repairIter(0)
00376 {
00377     m_content = new _TContent();
00378 }   
00379 
00380 template<class _TContent>
00381 Node<_TContent>::Node(const _TContent& content)
00382     :   m_parent(0), m_root(0),
00383         m_right_sibling(0), m_left_sibling(0),
00384         m_content(0),
00385         m_protected(false), m_fixed(false),
00386         m_name("no name"), m_repairIter(0)
00387 {
00388     m_content = new _TContent(content);
00389 }
00390 
00391 /**
00392   * Copy Constructor.
00393   * only content is a real copy. For parent, root and children only the
00394   * pointer is copied. For a real copy use cloneTree()
00395   */
00396 template<class _TContent>
00397 Node<_TContent>::Node(const Node<_TContent>& node)
00398     :   m_parent(node.m_parent), m_root(node.m_root),
00399         m_right_sibling(node.m_right_sibling), m_left_sibling(node.m_left_sibling),
00400         m_children(node.m_children),
00401         m_content(0),
00402         m_protected(node.m_protected), m_fixed(node.m_fixed),
00403         m_name(node.m_name,0,std::string::npos),
00404         m_repairIter(node.m_repairIter)
00405 {
00406     m_content = new _TContent(*node.m_content);
00407 }
00408 
00409 
00410 
00411 /**
00412  * Destructor. Works recursivly.
00413  */
00414 template<class _TContent>
00415 Node<_TContent>::~Node()
00416 {
00417     delete m_content;
00418 
00419     typename std::list<Node*>::iterator nlIter;
00420     for(nlIter = m_children.begin(); nlIter != m_children.end(); ++nlIter)
00421         if (*nlIter)
00422             delete (*nlIter);
00423 }
00424 
00425 
00426 /** Get the maximal depth of the tree. */
00427 template<class _TContent>
00428 int Node<_TContent>::getDepth() const
00429 {
00430     const_all_iterator anIter(this);
00431     DepthVisitor<_TContent, const_all_iterator > depthvisitor;
00432     depthvisitor( anIter );
00433     return depthvisitor.getDepth();
00434 }
00435 
00436 
00437 /**
00438  * Add a pointer to a child to the node (insert in front)
00439  * @param node The node to add
00440  */
00441 template<class _TContent>
00442 bool Node<_TContent>::addChildFront(Node* node)
00443 {
00444     assert(node != 0);
00445     // add is only possible if 'this' is not inner node of a protected tree
00446     if (isInner())
00447         return false;
00448 
00449     node->m_left_sibling = 0;
00450     if (m_children.size()==0)
00451         node->m_right_sibling = 0;
00452     else
00453     {
00454 //      node->m_left_sibling = m_children.front()->m_left_sibling;
00455         node->m_right_sibling = m_children.front();
00456 //      node->m_left_sibling->right_sibling = node;
00457         node->m_right_sibling->m_left_sibling = node;
00458     }
00459 
00460 
00461     m_children.push_front(node);
00462 //  if (m_children.size()==1)
00463 //      node->recalcSiblings();
00464     node->setProtected(true);
00465     node->setParent(this);
00466     node->recalcLeaves();
00467     return true;
00468 }
00469 
00470 /**
00471  * Add a pointer to a child node to the node (add to back)
00472  * @param node The node to add
00473  */
00474 template<class _TContent>
00475 bool Node<_TContent>::addChildBack(Node* node)
00476 {
00477     assert(node != 0);
00478     // add is only possible if 'this' is not inner node of a protected tree
00479     if (isInner())
00480         return false;
00481 
00482     if (m_children.size()==0)
00483         node->m_left_sibling = 0;
00484     else
00485     {
00486         node->m_left_sibling = m_children.back();
00487 //      node->m_right_sibling = m_children.back()->m_right_sibling;
00488         node->m_left_sibling->m_right_sibling = node;
00489 //      node->m_right_sibling->m_left_sibling = node;
00490     }
00491     node->m_right_sibling = 0;
00492 
00493     m_children.push_back(node);
00494 
00495 //  if (m_children.size()==1)
00496 //      node->recalcSiblings();
00497     node->setProtected(true);
00498     node->setParent(this);
00499     node->recalcLeaves();
00500     return true;
00501 }
00502 
00503 /**
00504  * Add a pointer to a child node to the node (insert it where the last one was deleted)
00505  * @param node The node to add
00506  */
00507 template<class _TContent>
00508 bool Node<_TContent>::addChild(Node* node)
00509 {
00510     assert(node != 0);
00511     // add is only possible if 'this' is not inner node of a protected tree
00512     if (isInner())
00513         return false;
00514     if (m_repairIter==0 )
00515         return addChildBack(node);
00516 
00517     if (!addChild(node,m_repairIter))
00518         return false;
00519     m_repairIter=0;
00520     return true;
00521 }
00522 
00523 /**
00524  * Add a pointer to a child to the node (insert it at position index)
00525  + index 0: push_front
00526  + index > number of children: push_back
00527  * @param node The node to add
00528  * @param index The position where to add, the child at that position is moved to the back
00529  */
00530 template<class _TContent>
00531 bool Node<_TContent>::addChild(Node* node, unsigned int index)
00532 {
00533     assert(node != 0);
00534     // add is only possible if 'this' is not inner node of a protected tree
00535     if (isInner())
00536         return false;
00537     if (index >= m_children.size())
00538         return addChildBack(node);
00539     if (index == 0)
00540         return addChildFront(node);
00541 
00542     typename std::list<Node<_TContent>*>::iterator nlIter = m_children.begin();
00543     unsigned int i;
00544     for (i=0 ; i<index; ++i)
00545         nlIter++;
00546     return addChild(node,nlIter);
00547 }
00548 
00549 /**
00550  * Add a child to the node (insert it before the position the iterator points to)
00551  * @param node The node to add
00552  * @param iter The iterator that gives the position
00553  */
00554 template<class _TContent>
00555 bool Node<_TContent>::addChild(Node* node, typename std::list<Node*>::iterator& iter)
00556 {
00557     assert(node != 0);
00558     // add is only possible if 'this' is not inner node of a protected tree
00559     if (isInner())
00560         return false;
00561 
00562     if (m_children.size()==0 || iter==m_children.begin())
00563         return addChildFront(node);
00564     if (iter==m_children.end())
00565         return addChildBack(node);
00566 
00567     node->m_left_sibling = *iter;
00568     node->m_right_sibling = (*iter)->m_right_sibling;
00569     node->m_left_sibling->m_right_sibling = node;
00570     node->m_right_sibling->m_left_sibling = node;
00571     node->setProtected(true);
00572     node->setParent(this);
00573 
00574     m_children.insert(iter, node);
00575     node->recalcLeaves();
00576     return true;
00577 }
00578 
00579 /**
00580  * Check if the node is inner node of a protected tree.
00581  * Returns 'True' if yes, 'False' if not.
00582  */
00583 template<class _TContent>
00584 bool Node<_TContent>::isInner() const
00585 {
00586     if (m_root)
00587     {
00588         // 'this' is already part of a tree
00589         const std::list<Node<_TContent>*>* leaves = m_root->getLeaves();
00590         bool isInLeaves = std::find( leaves->begin(),leaves->end(),this ) != leaves->end();
00591         if (m_root->isProtected() && !isInLeaves )
00592             return true;
00593     }
00594     return false;
00595 }
00596 
00597 /**
00598  * Delete a child from the node
00599  * Returns a list of the children of the deleted node.
00600  * (the list is empty if node is fixed and therefore not deleted, or if the node was a leave)
00601  * @param node The node to delete
00602  */
00603 template<class _TContent>
00604 std::list<Node<_TContent>*> Node<_TContent>::deleteChild(Node* node)
00605 {
00606     assert(node != 0);
00607 
00608     std::list<Node<_TContent>*> nodechildren;
00609     if (cutChild(node))
00610     {
00611         // get the node's children to return them
00612         nodechildren = node->m_children;
00613         typename std::list<Node<_TContent>*>::const_iterator nlIter;
00614         if (node->isRootNode())
00615         {
00616             // node is RootNode
00617             // -> nodechildren are the leaves children
00618             const std::list<Node<_TContent>*> leaves = *(node->getLeaves());
00619             nodechildren.clear();
00620             for (nlIter = leaves.begin(); nlIter != leaves.end(); ++nlIter)
00621                 nodechildren.merge((*nlIter)->m_children);
00622         }
00623         // disconnect nodechildren from node
00624         for (nlIter = nodechildren.begin(); nlIter != nodechildren.end(); ++nlIter)
00625             (*nlIter)->deleteParent();
00626         node->disconnectChildren();
00627     }
00628     return nodechildren;
00629 }
00630 
00631 /**
00632  * Delete a child from the node
00633  * Doesn't delete the child.
00634  * @param node The node to delete
00635  */
00636 template<class _TContent>
00637 bool Node<_TContent>::cutChild(Node* node)
00638 {
00639     assert(node != 0);
00640 
00641     if (!node->isFixed() && !m_children.empty())
00642     {
00643         // set repair iterator to the next child after node
00644         m_repairIter = std::find( m_children.begin(),m_children.end(),node );
00645         ++m_repairIter;
00646         m_children.remove(node);
00647         node->deleteParent();
00648         if (node->m_left_sibling)
00649             node->m_left_sibling->m_right_sibling = node->m_right_sibling;
00650         if (node->m_right_sibling)
00651             node->m_right_sibling->m_left_sibling = node->m_left_sibling;
00652         node->m_left_sibling=0;
00653         node->m_right_sibling=0;
00654         return true;
00655     }
00656     return false;
00657 }
00658 
00659 
00660 
00661 /**
00662  * Set the nodes parent.
00663  * This method is called if the node is added as
00664  * child.
00665  * @param node The node to add as parent
00666  */
00667 template<class _TContent>
00668 void Node<_TContent>::setParent(Node* node)
00669 {
00670     if (node==0)
00671     {
00672         deleteParent();
00673         return;
00674     }
00675     m_parent = node;
00676 
00677     if (node != 0)
00678     {
00679         // set root to the next root that's not protected
00680         Node* root = node->getRoot();
00681         if (root)
00682         {
00683             while (root->isProtected())
00684                 root = root->getRoot();
00685             m_root = root;
00686             // if 'this' is a normalNode then all of its children get the same root
00687             if (!isRootNode())
00688                 for (iterator nIter = begin(); nIter != end(); ++nIter)
00689                     (*nIter).m_root = root;
00690         }
00691         else
00692             m_root = node;
00693     }
00694 }
00695 
00696 /**
00697  * Delete the nodes parent.
00698  * This method is called if the node as child is removed.
00699  */
00700 template<class _TContent>
00701 void Node<_TContent>::deleteParent()
00702 {
00703     m_parent = 0;
00704     // set root value to default
00705     if (isRootNode())
00706         m_root = this;
00707     else
00708         m_root = 0;
00709 }
00710 
00711 /**
00712  * Delete references to the nodes children.
00713  * This method is called if the node as child is removed.
00714  */
00715 template<class _TContent>
00716 void Node<_TContent>::disconnectChildren()
00717 {
00718     m_children.clear();
00719 }
00720 
00721 /**
00722  * Reduce connected fixed parts of the tree to RootNodes
00723  */
00724 template<class _TContent>
00725 void Node<_TContent>::reduce()
00726 {}
00727 
00728 
00729 /**
00730  * Sets the sibling links of node's children right
00731  */
00732 template<class _TContent>
00733 void Node<_TContent>::linkSiblings()
00734 {
00735     Node<_TContent>* before;
00736     Node<_TContent>* after;
00737     typename std::list<Node<_TContent>*>::const_iterator nlIter,afterIter;
00738     nlIter = m_children.begin();
00739     nlIter++;
00740     nlIter++;
00741     before = 0;
00742     after = *nlIter;
00743     afterIter = nlIter;
00744 
00745     for (nlIter=m_children.begin(); nlIter!=m_children.end(); nlIter++,afterIter++)
00746     {
00747         (*nlIter)->m_left_sibling = before;
00748         (*nlIter)->m_left_sibling = after;      
00749         before = *nlIter;
00750         if (afterIter!=m_children.end())
00751             after = *afterIter;
00752         else
00753             after = 0;
00754     }
00755 }
00756 
00757 
00758 
00759 // ==================
00760 // === NormalNode ===
00761 // ==================
00762 
00763 
00764 /**
00765 * Simulated Copy Constructor
00766 * All children are duplicated, pointers to root and parent are preserved
00767 */
00768 template<class _TContent>
00769 NormalNode<_TContent>* NormalNode<_TContent>::cloneTree() const
00770 {
00771     NormalNode<_TContent>* newNode = new NormalNode<_TContent>(*this);
00772     newNode->m_children.clear();
00773 
00774     // nodeMap holds the relation between new nodes and old ones
00775     // so by using nodeMap[nodeX] you get the newNode equivalent to nodeX
00776     OldNewMap nodeMap;
00777     nodeMap.insert( typename OldNewMap::value_type(this, newNode) );
00778 
00779     // duplicate children
00780     typename std::list<Node<_TContent>*>::const_iterator nlIter;
00781     for (nlIter = m_children.begin(); nlIter != m_children.end(); ++nlIter)
00782         newNode->m_children.push_back( (*nlIter)->copy(nodeMap) );
00783     newNode->linkSiblings();
00784     return newNode;
00785 }
00786 
00787 /**
00788 * Simulated Copy Constructor for the Node,
00789 * pointer to root, parent and children are preserved, but the children
00790 * are not duplicated
00791 */
00792 template<class _TContent>
00793 NormalNode<_TContent>* NormalNode<_TContent>::cloneNode() const
00794 {
00795     NormalNode<_TContent>* newNode = new NormalNode<_TContent>(*this);
00796 //  newNode->m_content = new _TContent(*m_content);
00797     return newNode;
00798 }
00799 
00800 
00801 /**
00802  * Copy Node and its children recursively (is used by cloneTree)
00803  * @param nodeMap This map holds old-new node pairs of the ancestors of this
00804  */
00805 template<class _TContent>
00806 Node<_TContent>* NormalNode<_TContent>::copy(OldNewMap& nodeMap) const
00807 {
00808     NormalNode<_TContent>* newNode = new NormalNode<_TContent>(*this);
00809     newNode->m_root = nodeMap[m_root];
00810     newNode->m_parent = nodeMap[m_parent];
00811     newNode->m_children.clear();
00812     
00813     nodeMap.insert( typename OldNewMap::value_type(this, newNode) );
00814 
00815     // duplicate children
00816     typename std::list<Node<_TContent>*>::const_iterator nlIter;
00817     for (nlIter = m_children.begin(); nlIter != m_children.end(); ++nlIter)
00818         newNode->m_children.push_back( (*nlIter)->copy(nodeMap) );
00819     newNode->linkSiblings();
00820     return newNode;
00821 }
00822 
00823 /**
00824  * Accept a visitor. Calls the visitors visitNormalNode
00825  * method with this node.
00826  * @param visitor The visitor to visit
00827  */
00828 template<class _TContent>
00829 void
00830 NormalNode<_TContent>::acceptVisitor(
00831     NodeVisitorBase<Node<_TContent>,NormalNode<_TContent>,RootNode<_TContent> >*
00832     visitor)
00833 {
00834     visitor->visitNormalNode(this);
00835 }
00836 
00837 /**
00838  * Accept a const visitor. Calls the visitors visitNormalNode
00839  * method with this node.
00840  * @param visitor The visitor to visit
00841  */
00842 template<class _TContent>
00843 void
00844 NormalNode<_TContent>::acceptVisitor(
00845     NodeVisitorBase<const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >*
00846     visitor) const
00847 {
00848     visitor->visitNormalNode(this);
00849 }
00850 
00851 
00852 
00853 // =================
00854 // === RootNode ===
00855 // =================
00856 /**
00857  * Constructor
00858  */
00859 template<class _TContent>
00860 RootNode<_TContent>::RootNode()
00861     : Node<_TContent>()
00862 {
00863     m_root = this;
00864 }
00865 
00866 /**
00867 * Simulated Copy Constructor for the tree.
00868 * All children are duplicated, pointers to root and parent are preserved
00869 */
00870 template<class _TContent>
00871 RootNode<_TContent>* RootNode<_TContent>::cloneTree() const
00872 {
00873     RootNode<_TContent>* newNode = new RootNode<_TContent>(*this);
00874     newNode->m_root = newNode;
00875     newNode->m_children.clear();
00876 
00877     // nodeMap holds the relation between new nodes and old ones
00878     // so by using nodeMap[nodeX] you get the newNode equivalent to nodeX
00879     OldNewMap nodeMap;
00880     nodeMap.insert( typename OldNewMap::value_type(this, newNode) );
00881 
00882     // duplicate children
00883     typename std::list<Node<_TContent>*>::const_iterator nlIter;
00884     for (nlIter = m_children.begin(); nlIter != m_children.end(); ++nlIter)
00885         newNode->m_children.push_back( (*nlIter)->copy(nodeMap) );
00886     newNode->linkSiblings();
00887     return newNode;
00888 }
00889 
00890 /**
00891 * Simulated Copy Constructor for the Node,
00892 * pointer to root, parent and children are preserved, but the children
00893 * are not duplicated
00894 */
00895 template<class _TContent>
00896 RootNode<_TContent>* RootNode<_TContent>::cloneNode() const
00897 {
00898     RootNode<_TContent>* newNode = new RootNode<_TContent>(*this);
00899     newNode->m_content = new _TContent(*m_content);
00900     return newNode;
00901 }
00902 
00903 
00904 /**
00905  * Copy Node and its children recursively (is used by cloneTree)
00906  * @param nodeMap This map holds old-new node pairs of the ancestors of this
00907  */
00908 template<class _TContent>
00909 Node<_TContent>* RootNode<_TContent>::copy(OldNewMap& nodeMap) const
00910 {
00911     RootNode<_TContent>* newNode = new RootNode<_TContent>(*this);
00912     newNode->m_root = nodeMap[m_root];
00913     newNode->m_parent = nodeMap[m_parent];
00914     newNode->m_children.clear();
00915     
00916     nodeMap.insert( typename OldNewMap::value_type(this, newNode) );
00917 
00918     // duplicate children
00919     typename std::list<Node<_TContent>*>::const_iterator nlIter;
00920     for (nlIter = m_children.begin(); nlIter != m_children.end(); ++nlIter)
00921         newNode->m_children.push_back( (*nlIter)->copy(nodeMap) );
00922     newNode->linkSiblings();
00923     return newNode;
00924 }
00925 
00926 /**
00927  * Accept a visitor. Calls the visitors visitRootNode
00928  * method with this node.
00929  * @param visitor Visitor to visit
00930  */
00931 template<class _TContent>
00932 void
00933 RootNode<_TContent>::acceptVisitor(
00934     NodeVisitorBase<Node<_TContent>,NormalNode<_TContent>,RootNode<_TContent> >*
00935     visitor)
00936 {
00937     visitor->visitRootNode(this);
00938 }
00939 
00940 /**
00941  * Accept a const visitor. Calls the visitors visitRootNode
00942  * method with this node.
00943  * @param visitor Visitor to visit
00944  */
00945 template<class _TContent>
00946 void
00947 RootNode<_TContent>::acceptVisitor(
00948     NodeVisitorBase<const Node<_TContent>,const NormalNode<_TContent>,const RootNode<_TContent> >*
00949     visitor) const
00950 {
00951     visitor->visitRootNode(this);
00952 }
00953 
00954 
00955 /**
00956  * Get the number of descendants of this node.
00957  */
00958 template<class _TContent>
00959 size_t RootNode<_TContent>::getNumDescendants() const
00960 {
00961     int count = 0;
00962     typename Node<_TContent>::const_iterator nIter(this);
00963     for (; !nIter.isEnd(); ++nIter)
00964         ++count;
00965     return count-1;
00966 }
00967 
00968 /**
00969  * Update the list of leaves of this node.
00970  * Call this function after building a subtree that should later
00971  * be recognized as such.
00972  * Is automatically called if the node is added to another
00973  */
00974 template<class _TContent>
00975 void RootNode<_TContent>::recalcLeaves()
00976 {
00977     m_leaves.clear();
00978     typename Node<_TContent>::leave_iterator lIter(this);
00979     for (; !lIter.isEnd(); ++lIter)
00980         m_leaves.push_back(lIter());
00981 }
00982 
00983 /**
00984  * Make the RootNode a unit in the enclosing tree
00985  * Is automatically called with parameter 'true' if the node is added to another
00986  */
00987 template<class _TContent>
00988 void RootNode<_TContent>::setProtected(bool b)
00989 {
00990     m_protected = b;
00991 }
00992 
00993 /**
00994  * Delete the nodes parent.
00995  * This method is called if the node as child is removed.
00996  */
00997 template<class _TContent>
00998 void RootNode<_TContent>::deleteParent()
00999 {
01000     m_parent = 0;
01001     m_root = this;
01002 }
01003 
01004 
01005 } // namespace treecomp
01006 
01007 #endif //NODE_H

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