Tree.hpp

Go to the documentation of this file.
00001 
00015 #ifndef Tree_H
00016 #define Tree_H
00017 
00018 // STL headers
00019 #include <deque>
00020 #include <set>
00021 
00022 #include <OpenAnalysis/Utils/OA_ptr.hpp>
00023 #include <OpenAnalysis/OABase/Annotation.hpp>
00024 
00025 // Mint headers
00026 #include "Iterator.hpp"
00027 #include "Exception.hpp"
00028 
00029 namespace OA {
00030 
00031 //--------------------------------------------------------------------
00067 //--------------------------------------------------------------------
00068 class Tree : public virtual Annotation {
00069  public:
00070   class Node ;
00071   class Edge;
00072   class NodesIterator;
00073   class EdgesIterator;
00074   class PreOrderIterator;
00075   class PostOrderIterator;
00076   class ReversePostOrderIterator;
00077   class OutEdgesIterator;
00078   class ChildNodesIterator;
00079   friend class NodesIterator;
00080   friend class EdgesIterator;
00081   friend class PreOrderIterator;
00082   friend class PostOrderIterator;
00083   friend class ReversePostOrderIterator;
00084   //------------------------------------------------------------------
00086   class EmptyEdge : public Exception {
00087   public:
00088     EmptyEdge () {}
00089     ~EmptyEdge () {}
00090     void report (std::ostream& o) const { o << "E!  Adding a null edge to a tree." << std::endl; }
00091   };
00092   //------------------------------------------------------------------
00096   class DuplicateEdge : public Exception {
00097   public:
00098     DuplicateEdge (OA_ptr<Tree::Edge>  e) { offending_edge = e; }
00099     ~DuplicateEdge () {}
00100     void report (std::ostream& o) const { o << "E!  Adding a duplicate edge to a tree." << std::endl; }
00101   private:
00102     OA_ptr<Tree::Edge> offending_edge;
00103   };
00104   //------------------------------------------------------------------
00107   class NonexistentEdge : public Exception {
00108   public:
00109     NonexistentEdge (OA_ptr<Tree::Edge>  e) { offending_edge = e; }
00110     ~NonexistentEdge () {}
00111     void report (std::ostream& o) const { o << "E!  Removing a non-existent edge from a tree." << std::endl; }
00112   private:
00113     OA_ptr<Tree::Edge>  offending_edge;
00114   };
00115   //------------------------------------------------------------------
00119   class EdgeInUse : public Exception {
00120   public:
00121     EdgeInUse (OA_ptr<Tree::Edge>  e) { offending_edge = e; }
00122     ~EdgeInUse () {}
00123     void report (std::ostream& o) const { o << "E!  Adding an edge that is already a part of another tree." << std::endl; }
00124   private:
00125     OA_ptr<Tree::Edge>  offending_edge;
00126   };
00127   //------------------------------------------------------------------
00132   class SecondParent : public Exception {
00133   public:
00134     SecondParent (OA_ptr<Tree::Edge>  e) { offending_edge = e; }
00135     ~SecondParent () {}
00136     void report (std::ostream& o) const { o << "E!  Adding an edge that points to an existing node in the tree." << std::endl; }
00137   private:
00138     OA_ptr<Tree::Edge>  offending_edge;
00139   };
00140   //------------------------------------------------------------------
00144   class EmptyEndPoint : public Exception {
00145   public:
00146     EmptyEndPoint (OA_ptr<Tree::Edge>  e) { offending_edge = e; }
00147     ~EmptyEndPoint () {}
00148     void report (std::ostream& o) const { o << "E!  Adding an edge that points to an empty node." << std::endl; }
00149   private:
00150     OA_ptr<Tree::Edge>  offending_edge;
00151   };
00152   //------------------------------------------------------------------
00154   class EmptyNode : public Exception {
00155   public:
00156     EmptyNode () {}
00157     ~EmptyNode () {}
00158     void report (std::ostream& o) const { o << "E!  Adding a null node to a tree." << std::endl; }
00159   };
00160   //------------------------------------------------------------------
00164   class DuplicateNode : public Exception {
00165   public:
00166     DuplicateNode (OA_ptr<Tree::Node>  n) { offending_node = n; }
00167     ~DuplicateNode () {}
00168     void report (std::ostream& o) const { o << "E!  Adding a duplicate node to a tree." << std::endl; }
00169   private:
00170     OA_ptr<Tree::Node>  offending_node;
00171   };
00172   //------------------------------------------------------------------
00176   class NonexistentNode : public Exception {
00177   public:
00178     NonexistentNode (OA_ptr<Tree::Node>  n) { offending_node = n; }
00179     ~NonexistentNode () {}
00180     void report (std::ostream& o) const { o << "E!  Removing a non-existent node from the tree." << std::endl; }
00181   private:
00182     OA_ptr<Tree::Node>  offending_node;
00183   };
00184   //------------------------------------------------------------------
00188   class NodeInUse : public Exception {
00189   public:
00190     NodeInUse (OA_ptr<Tree::Node>  n) { offending_node = n; }
00191     ~NodeInUse () {}
00192     void report (std::ostream& o) const { o << "E!  Adding a node that is already a part of another tree." << std::endl; }
00193   private:
00194     OA_ptr<Tree::Node>  offending_node;
00195   };
00196   //------------------------------------------------------------------
00201   class DeletingRootOfNonSingletonTree : public Exception {
00202   public:
00203     DeletingRootOfNonSingletonTree (OA_ptr<Tree::Node>  n) { offending_node = n; }
00204     ~DeletingRootOfNonSingletonTree () {}
00205     void report (std::ostream& o) const { o << "E!  Deleting the root node of a non-singleton tree." << std::endl; }
00206   private:
00207     OA_ptr<Tree::Node>  offending_node;
00208   };
00209   //------------------------------------------------------------------
00214   class Node : public virtual Annotation {
00215   public:
00216     Node() 
00217         { in_use = false; 
00218           next_preorder = next_postorder = prev_postorder = 0;  
00219           incoming = 0; 
00220           outgoing = new std::deque<OA_ptr<Edge> >;
00221         }
00222     //virtual OA_ptr<Node> new_copy () 
00223     //    { OA_ptr<Node> n; n = new Node(); copy(n); return n; }
00224     virtual ~Node () {}
00225 
00226 
00227     OA_ptr<Node> parent () const 
00228         { OA_ptr<Node> retval; retval=0;
00229           if (!incoming.ptrEqual(0)) {
00230             retval = incoming->source(); 
00231           } 
00232           return retval;
00233         }
00234     OA_ptr<Node> child (int i) const 
00235         { OA_ptr<Node> retval; retval = 0;
00236           if (! (*outgoing)[i].ptrEqual(0)) {
00237             retval = (*outgoing)[i]->child(); 
00238           } 
00239           return retval;
00240         }
00241 
00242     OA_ptr<Edge>  in_edge () const { return incoming; }
00243     OA_ptr<Edge>  out_edge (int i) const { return (*outgoing)[i]; }
00244     int num_children () const { return outgoing->size(); }
00245     virtual bool operator==(Node& other) { return &other==this; }
00246     virtual bool operator<(Node& other) { return this<&other; }
00247     virtual void dump (std::ostream& os) { os << this; }
00248     
00249     //*****************************************************************
00250     // Annotation Interface
00251     //*****************************************************************
00252     virtual void output(IRHandlesIRInterface& ir) {
00253       ostringstream label;
00254       label << this; // what does this print, anyway?
00255       sOutBuild->outputString( label.str() );
00256     }
00257 
00258     // Iterators
00259     OA_ptr<OutEdgesIterator> 
00260     getOutEdgesIterator() const {
00261       OA_ptr<OutEdgesIterator> it; it = new OutEdgesIterator(*this);
00262       return it;
00263     }
00264     
00265     OA_ptr<ChildNodesIterator> 
00266     getChildNodesIterator() const {
00267       OA_ptr<ChildNodesIterator> it; it = new ChildNodesIterator(*this);
00268       return it;
00269     }
00270 
00271   protected:
00272     //virtual void copy (OA_ptr<Node>  n) {}
00273     OA_ptr<Edge>  incoming;
00274     OA_ptr<std::deque<OA_ptr<Edge> > > outgoing;
00275     OA_ptr<Node>  next_preorder;
00276     OA_ptr<Node>  next_postorder;
00277     OA_ptr<Node>  prev_postorder;
00278     bool in_use;
00279     friend class Tree;
00280     friend class Tree::PreOrderIterator;
00281     friend class Tree::PostOrderIterator;
00282     friend class Tree::ReversePostOrderIterator;
00283     friend class Tree::OutEdgesIterator;
00284     friend class Tree::ChildNodesIterator;
00285   };
00286   //------------------------------------------------------------------
00288   class Edge {
00289   public:
00290     Edge (OA_ptr<Node>  _source, OA_ptr<Node>  _sink) 
00291         { in_use = false; parent_node = _source; child_node = _sink; }
00292     //virtual OA_ptr<Edge> new_copy (OA_ptr<Node>  _src, OA_ptr<Node>  _snk) 
00293     //    { OA_ptr<Edge>  e; e = new Edge(_src, _snk); copy(e); return e; }
00294     virtual ~Edge () {}
00295     virtual bool operator==(Edge& other) 
00296         {
00297             if (other.parent_node == parent_node 
00298                 && other.child_node == child_node )
00299             { return true; }
00300             else { return false; }
00301         }
00302     virtual bool operator<(Edge& other) 
00303         {
00304             if (*this==other) { return false; }
00305             if (parent_node < other.parent_node) { return true; }
00306             if (child_node < other.child_node) { return true; }
00307             return false; 
00308         }
00309     OA_ptr<Node>  parent () const { return parent_node; }
00310     OA_ptr<Node>  source () const { return parent(); }
00311     OA_ptr<Node>  tail () const { return parent(); }
00312     OA_ptr<Node>  child () const { return child_node; }
00313     OA_ptr<Node>  sink () const { return child(); }
00314     OA_ptr<Node>  head () const { return child(); }
00315     virtual void dump (std::ostream& os) { os << this; }
00316   protected:
00317     //void copy (OA_ptr<Edge>  e) {}
00318     OA_ptr<Node>  parent_node;
00319     OA_ptr<Node>  child_node;
00320     bool in_use;
00321     friend class Tree;
00322     friend class Tree::Node;
00323   };
00324   //------------------------------------------------------------------
00328   class NodesIterator : public Iterator {
00329   public:
00330     NodesIterator (const Tree& t) { mSet = t.node_set;  
00331         mIter = mSet->begin(); }
00332     virtual ~NodesIterator () {}
00333     void operator++ () { ++mIter; }
00334     void operator++(int) { ++*this; }  // postfix
00335     bool isValid() const { return (mIter != mSet->end()); }
00336     OA_ptr<Node>  current() const { return *mIter; }
00337 
00338   protected:
00339     OA_ptr<std::set<OA_ptr<Node> > > mSet;
00340     std::set<OA_ptr<Node> >::iterator mIter;
00341   };
00342   //------------------------------------------------------------------
00346   class EdgesIterator : public Iterator {
00347   public:
00348     EdgesIterator (const Tree& t) { mSet = t.edge_set; 
00349         mIter = mSet->begin(); }
00350     virtual ~EdgesIterator () {}
00351     void operator++ () { ++mIter; }
00352     void operator++(int) { ++*this; }  // postfix
00353     bool isValid() const { return (mIter != mSet->end()); }
00354     OA_ptr<Edge>  current() const { return *mIter; }
00355 
00356   protected:
00357     OA_ptr<std::set<OA_ptr<Edge> > > mSet;
00358     std::set<OA_ptr<Edge> >::iterator mIter;
00359   };
00360   //------------------------------------------------------------------
00364   class OutEdgesIterator : public Iterator {
00365   public:
00366     OutEdgesIterator (const Node& n);
00367     virtual ~OutEdgesIterator () {}
00368     void operator++ ();
00369     void operator++(int) { ++*this; }  // postfix
00370     bool isValid() const { return (mIter != mQueue->end()); }
00371     OA_ptr<Edge>  current() const { return *mIter; }
00372 
00373   private:
00374     OA_ptr<std::deque<OA_ptr<Edge> > > mQueue;
00375     std::deque<OA_ptr<Edge> >::iterator mIter;
00376   };
00377   //------------------------------------------------------------------
00381   class ChildNodesIterator : private OutEdgesIterator {
00382   public:
00383     ChildNodesIterator(const Node& n) : OutEdgesIterator(n) {}
00384     ~ChildNodesIterator() {}
00385     void operator++() { OutEdgesIterator::operator++(); }
00386     void operator++(int) { ++*this; }  // postfix
00387     bool isValid() const { return OutEdgesIterator::isValid(); }
00388     OA_ptr<Node>  current() const
00389     { OA_ptr<Edge>  e = OutEdgesIterator::current();  return e->sink(); }
00390 
00391   };
00392   //------------------------------------------------------------------
00396   class PreOrderIterator : public Iterator {
00397   public:
00398     PreOrderIterator(Tree& t);
00399     virtual ~PreOrderIterator() {}
00400     void operator++() { if (!p.ptrEqual(0)) p = p->next_preorder; }
00401     void operator++(int) { ++*this; }  // postfix
00402     bool isValid() const { return (!p.ptrEqual(0)); }
00403     OA_ptr<Node>  current() const { return p; }
00404 
00405   private:
00406     OA_ptr<Node>  p; // pointer to the last visited node
00407   };
00408   //------------------------------------------------------------------
00428   class PostOrderIterator : public Iterator {
00429   public:
00430     PostOrderIterator(Tree& t);
00431     virtual ~PostOrderIterator() {}
00432     void operator++() { if (isValid()) p = p->next_postorder; }
00433     void operator++(int) { ++*this; }  // postfix
00434     bool isValid() const { return (!p.ptrEqual(0)); }
00435     OA_ptr<Node>  current() const { return p; }
00436 
00437   private:
00438     OA_ptr<Node>  p; // pointer to the last visited node
00439   };
00440   //------------------------------------------------------------------
00444   class ReversePostOrderIterator : public Iterator {
00445   public:
00446     ReversePostOrderIterator (const Tree& t);
00447     virtual ~ReversePostOrderIterator () {}
00448     void operator++ () { if (!p.ptrEqual(0)) p = p->prev_postorder; }
00449     void operator++(int) { ++*this; }  // postfix
00450     bool isValid() const { return (!p.ptrEqual(0)); }
00451     OA_ptr<Node>  current() const { return p; }
00452 
00453   private:
00454     OA_ptr<Node>  p; // pointer to the last visited node
00455   };
00456 
00457   //------------------------------------------------------------------
00458 public:
00459   Tree() 
00460       { root_node = 0;
00461         edge_set = new std::set<OA_ptr<Edge> >;
00462         node_set = new std::set<OA_ptr<Node> >; }
00463   Tree(OA_ptr<Node>  root) { addNode(root); }
00464   virtual ~Tree() {}
00465   
00466   OA_ptr<Node>  getRoot() { return root_node; }
00467 
00468   void addEdge(OA_ptr<Edge> ) 
00469     throw (DuplicateEdge, EdgeInUse, EmptyEdge, SecondParent, EmptyEndPoint);
00470   void addNode(OA_ptr<Node> ) throw (DuplicateNode, NodeInUse, EmptyNode);
00471   void add_empty_edge(OA_ptr<Node> ) throw (EmptyNode);
00472   void removeEdge(OA_ptr<Edge> ) throw (NonexistentEdge, EmptyEdge);
00473   void removeNode(OA_ptr<Node> ) 
00474       throw (NonexistentNode, DeletingRootOfNonSingletonTree, EmptyNode);
00475   //OA_ptr<Node>  clone (OA_ptr<Node> );
00476 
00477   //*****************************************************************
00478   // Annotation Interface
00479   //*****************************************************************
00480   virtual void output(IRHandlesIRInterface& ir) { }
00481 
00482 
00483   //------------------------------------------------------------------
00484   // Iterators
00485   //------------------------------------------------------------------
00486   
00487   OA_ptr<NodesIterator> getNodesIterator() const { 
00488     OA_ptr<NodesIterator> it; it = new NodesIterator(*this);
00489     return it;
00490   }
00491 
00492   OA_ptr<EdgesIterator> getEdgesIterator() const {
00493     OA_ptr<EdgesIterator> it; it = new EdgesIterator(*this);
00494     return it;
00495   }
00496 
00497   OA_ptr<PreOrderIterator> getPreOrderIterator() {
00498     OA_ptr<PreOrderIterator> it; it = new PreOrderIterator(*this);
00499     return it;
00500   }
00501 
00502   OA_ptr<PostOrderIterator> getPostOrderIterator() {
00503     OA_ptr<PostOrderIterator> it; it = new PostOrderIterator(*this);
00504     return it;
00505   }
00506   
00507   OA_ptr<ReversePostOrderIterator> getReversePostOrderIterator() const {
00508     OA_ptr<ReversePostOrderIterator> it; 
00509     it = new ReversePostOrderIterator(*this);
00510     return it;
00511   }
00512 
00513 
00514 protected:
00515   OA_ptr<Node>  root_node;
00516   OA_ptr<Node>  mPostOrderStart;
00517   OA_ptr<std::set<OA_ptr<Edge> > > edge_set;
00518   OA_ptr<std::set<OA_ptr<Node> > > node_set;
00519   bool preorder_needed;
00520   bool postorder_needed;
00521   bool rpostorder_needed;
00522 
00523 private:
00524   OA_ptr<Node> create_preorder_links ( OA_ptr<Node> );
00525   OA_ptr<Node> create_postorder_links ( OA_ptr<Node>, OA_ptr<Node> );
00526   //OA_ptr<Node>  create_rpostrder_links ( OA_ptr<Node> );
00527 };
00528 //--------------------------------------------------------------------
00529 
00530 } // end of OA namespace
00531 
00532 #endif