Go to the documentation of this file.00001
00015 #ifndef Tree_H
00016 #define Tree_H
00017
00018
00019 #include <deque>
00020 #include <set>
00021
00022 #include <OpenAnalysis/Utils/OA_ptr.hpp>
00023 #include <OpenAnalysis/OABase/Annotation.hpp>
00024
00025
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
00223
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
00251
00252 virtual void output(IRHandlesIRInterface& ir) {
00253 ostringstream label;
00254 label << this;
00255 sOutBuild->outputString( label.str() );
00256 }
00257
00258
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
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
00293
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
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; }
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; }
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; }
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; }
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; }
00402 bool isValid() const { return (!p.ptrEqual(0)); }
00403 OA_ptr<Node> current() const { return p; }
00404
00405 private:
00406 OA_ptr<Node> p;
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; }
00434 bool isValid() const { return (!p.ptrEqual(0)); }
00435 OA_ptr<Node> current() const { return p; }
00436
00437 private:
00438 OA_ptr<Node> p;
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; }
00450 bool isValid() const { return (!p.ptrEqual(0)); }
00451 OA_ptr<Node> current() const { return p; }
00452
00453 private:
00454 OA_ptr<Node> p;
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
00476
00477
00478
00479
00480 virtual void output(IRHandlesIRInterface& ir) { }
00481
00482
00483
00484
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
00527 };
00528
00529
00530 }
00531
00532 #endif