/* * CTree.h * $Id: CTree.h,v 1.10 2001/11/23 02:03:35 mjanich Exp $ * * Copyright (C) 2001 Markus Janich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception to the GPL, the QGLViewer authors (Markus * Janich, Michael Meissner, Richard Guenther, Alexander Buck and Thomas * Woerner) give permission to link this program with Qt (non-)commercial * edition, and distribute the resulting executable, without including * the source code for the Qt (non-)commercial edition in the source * distribution. * */ #ifndef CTREE_H #define CTREE_H // Own //////// #include "CList.h" // System /////////// #include // forward declarations ///////////////////////// class CTreeTraverserBase; /** This class implements a node that can be inserted * into a tree. */ class CTreeNode { public: enum Where { Front, End }; /**< */ /** Default constructor. */ CTreeNode() : m_pcParent(0) { #ifdef DEBUG_TREE cerr << "called CTreeNode::CTreeNode()" << endl; #endif /* nothing to do */}; /** Copy constructor. */ CTreeNode(const CTreeNode &cSource); /** Destructor. */ virtual ~CTreeNode(); /** Appends the node 'cNode' to the children list * of this node. */ virtual CTreeNode *append(CTreeNode *pcNode, Where w=End) { return append(this, pcNode, w); }; /** Appends the node 'pcAppend' to the children list * of node 'pcWhere'. The tree makes a copy of the node, so * you can delete the source after appending. */ virtual CTreeNode *append(CTreeNode *pcWhere, CTreeNode *pcAppend, Where w=End) { if (pcWhere) { switch (w) { case End: pcWhere->m_cChildrenList.insertAsLast(pcAppend); break; case Front: pcWhere->m_cChildrenList.insertAsFirst(pcAppend); break; } pcAppend->m_pcParent = pcWhere; return pcAppend; } return 0; }; /** Exchanges the node 'pcWhere' against 'pcInsert'. The node * 'pcWhere' will be appended to the children list of 'pcInsert'. * The parent node of the inserted one is returned. */ virtual CTreeNode *insert(CTreeNode *pcWhere, CTreeNode *pcInsert); // FIXME: conflicts with traversers /////////////////////////////////////// /** Remove the specified node from the tree. */ virtual void remove(CTreeNode *pcRemove); /** Remove the node which the iterater points to from the tree. */ virtual void remove(CTreeTraverserBase *pcTraverser); /** Replaces the node given by 'pcReplace' with another * given by 'pcWith'. */ virtual void replace(CTreeNode *pcReplace, CTreeNode *pcWith); /** Returns the parent node. */ virtual CTreeNode *getParent() const { return m_pcParent; }; /** Returns the number of children of this node. */ virtual int numChildren() const { return m_cChildrenList.getNumObjects(); }; /** Returns the list of children nodes of this node. */ virtual const CList &getChildrenList() const { return m_cChildrenList; } /** Assigns one node to another. */ virtual CTreeNode &operator=(const CTreeNode &cSource); /** Returns the i-th child of this node. * \par NOTE: If i<0 the program will exit with a message * and if i>numCildren() the last child is returned. */ virtual CTreeNode &operator[](int i) const; /** Compares two node. */ virtual bool isEqual(const CTreeNode *pcNode) const; /** Prints the tree that starts at this node in breath-first-order. */ virtual void printTree(ostream &out=cout) const; friend ostream& operator<<(ostream &out, CTreeNode *pcTreeNode); protected: /** */ virtual void print(ostream &out) const; /////////// // DATA // /////////// CTreeNode *m_pcParent; CList m_cChildrenList; }; /////////////////////////////////////////////////////////// //// HERE STARTS THE DECLARATION OF CTREETRAVERSBASE //// /////////////////////////////////////////////////////////// /** Base class of all tree traversers. * Declares the interface that all traverses * should implement. */ class CTreeTraverserBase { friend class CTreeNode; public: CTreeTraverserBase() {}; CTreeTraverserBase(CTreeNode *) {}; virtual ~CTreeTraverserBase() {}; virtual bool atStart() = 0; virtual bool atEnd() = 0; virtual const CTreeNode *operator++() = 0; virtual const CTreeNode *operator++(int dummy) = 0; //virtual const CTreeNode *operator--() = 0; //virtual const CTreeNode *operator--(int dummy) = 0; virtual CTreeNode *operator*() = 0; protected: virtual CTreeNode *getCurrentNode() const = 0; virtual void removeCurrentNode() = 0; }; //////////////////////////////////////////////// //// HERE STARTS THE DECLARATION OF //// //// CTREETRAVERSBASE'S IMPLEMENTATIONS //// //////////////////////////////////////////////// // FIXME:: They better should do their work directly // on the data of the tree instead of making // a list /** This class implements a traverser which * traverses a tree in depth-first-order. */ class CDepthFirstTraverser : public CTreeTraverserBase { public: CDepthFirstTraverser(CTreeNode *pcNode); virtual ~CDepthFirstTraverser() {}; virtual bool atStart(); virtual bool atEnd(); virtual const CTreeNode *operator++(); virtual const CTreeNode *operator++(int dummy); //virtual const CTreeNode *operator--(); //virtual const CTreeNode *operator--(int dummy); virtual CTreeNode *operator*() { return getCurrentNode(); } protected: virtual CTreeNode *getCurrentNode() const; virtual void removeCurrentNode(); private: void parseSubTree(CTreeNode *pcNode); CList m_cNodeList; CListContainer *m_pcCurrentNode; bool m_fAtEnd, m_fAtStart; int m_nLastOp; // 0: ++, 1: -- }; /** This class implements a traverser which * traverses a tree in breath-first-order. */ class CBreathFirstTraverser : public CTreeTraverserBase { public: CBreathFirstTraverser(CTreeNode *pcNode); virtual ~CBreathFirstTraverser() {}; virtual bool atStart(); virtual bool atEnd(); virtual const CTreeNode *operator++(); virtual const CTreeNode *operator++(int dummy); //virtual const CTreeNode *operator--(); //virtual const CTreeNode *operator--(int dummy); virtual CTreeNode *operator*() { return getCurrentNode(); } protected: virtual CTreeNode *getCurrentNode() const; virtual void removeCurrentNode(); private: CList m_cNodeList; CListContainer *m_pcCurrentNode; bool m_fAtEnd, m_fAtStart; int m_nLastOp; // 0: ++, 1: -- }; #endif // CTREE_H