Program Listing for File Tree.h

Program Listing for File Tree.h#

↰ Return to documentation for file (src/midend/programAnalysis/OpenAnalysis/Utils/Tree.h)

// $Id: Tree.h,v 1.1 2004/07/07 10:26:35 dquinlan Exp $
// -*-C++-*-
// * BeginRiceCopyright *****************************************************
//
// Copyright ((c)) 2002, Rice University
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
//
// * Neither the name of Rice University (RICE) nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// This software is provided by RICE and contributors "as is" and any
// express or implied warranties, including, but not limited to, the
// implied warranties of merchantability and fitness for a particular
// purpose are disclaimed. In no event shall RICE or contributors be
// liable for any direct, indirect, incidental, special, exemplary, or
// consequential damages (including, but not limited to, procurement of
// substitute goods or services; loss of use, data, or profits; or
// business interruption) however caused and on any theory of liability,
// whether in contract, strict liability, or tort (including negligence
// or otherwise) arising in any way out of the use of this software, even
// if advised of the possibility of such damage.
//
// ******************************************************* EndRiceCopyright *

// Best seen in 120-column wide window (or print in landscape mode).
//--------------------------------------------------------------------------------------------------------------------
// This file is part of Mint.
// Arun Chauhan (achauhan@cs.rice.edu), Dept of Computer Science, Rice University, 2001.
//--------------------------------------------------------------------------------------------------------------------

#ifndef Tree_H
#define Tree_H

// STL headers
#include <deque>
#include <set>

// Mint headers
#include "Iterator.h"
#include "Exception.h"


//--------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------
class Tree {
 public:
  class Node;
  class Edge;
  class NodesIterator;
  class EdgesIterator;
  class PreOrderIterator;
  class PostOrderIterator;
  class ReversePostOrderIterator;
  class OutEdgesIterator;
  class ChildNodesIterator;
  friend class NodesIterator;
  friend class EdgesIterator;
  friend class PreOrderIterator;
  friend class PostOrderIterator;
  friend class ReversePostOrderIterator;
  //------------------------------------------------------------------------------------------------------------------
  class EmptyEdge : public Exception {
  public:
    EmptyEdge () {}
    ~EmptyEdge () {}
    void report (std::ostream& o) const { o << "E!  Adding a null edge to a tree." << std::endl; }
  };
  //------------------------------------------------------------------------------------------------------------------
  class DuplicateEdge : public Exception {
  public:
    DuplicateEdge (Tree::Edge* e) { offending_edge = e; }
    ~DuplicateEdge () {}
    void report (std::ostream& o) const { o << "E!  Adding a duplicate edge to a tree." << std::endl; }
  private:
    Tree::Edge* offending_edge;
  };
  //------------------------------------------------------------------------------------------------------------------
  class NonexistentEdge : public Exception {
  public:
    NonexistentEdge (Tree::Edge* e) { offending_edge = e; }
    ~NonexistentEdge () {}
    void report (std::ostream& o) const { o << "E!  Removing a non-existent edge from a tree." << std::endl; }
  private:
    Tree::Edge* offending_edge;
  };
  //------------------------------------------------------------------------------------------------------------------
  class EdgeInUse : public Exception {
  public:
    EdgeInUse (Tree::Edge* e) { offending_edge = e; }
    ~EdgeInUse () {}
    void report (std::ostream& o) const { o << "E!  Adding an edge that is already a part of another tree." << std::endl; }
  private:
    Tree::Edge* offending_edge;
  };
  //------------------------------------------------------------------------------------------------------------------
  class SecondParent : public Exception {
  public:
    SecondParent (Tree::Edge* e) { offending_edge = e; }
    ~SecondParent () {}
    void report (std::ostream& o) const { o << "E!  Adding an edge that points to an existing node in the tree." << std::endl; }
  private:
    Tree::Edge* offending_edge;
  };
  //------------------------------------------------------------------------------------------------------------------
  class EmptyEndPoint : public Exception {
  public:
    EmptyEndPoint (Tree::Edge* e) { offending_edge = e; }
    ~EmptyEndPoint () {}
    void report (std::ostream& o) const { o << "E!  Adding an edge that points to an empty node." << std::endl; }
  private:
    Tree::Edge* offending_edge;
  };
  //------------------------------------------------------------------------------------------------------------------
  class EmptyNode : public Exception {
  public:
    EmptyNode () {}
    ~EmptyNode () {}
    void report (std::ostream& o) const { o << "E!  Adding a null node to a tree." << std::endl; }
  };
  //------------------------------------------------------------------------------------------------------------------
  class DuplicateNode : public Exception {
  public:
    DuplicateNode (Tree::Node* n) { offending_node = n; }
    ~DuplicateNode () {}
    void report (std::ostream& o) const { o << "E!  Adding a duplicate node to a tree." << std::endl; }
  private:
    Tree::Node* offending_node;
  };
  //------------------------------------------------------------------------------------------------------------------
  class NonexistentNode : public Exception {
  public:
    NonexistentNode (Tree::Node* n) { offending_node = n; }
    ~NonexistentNode () {}
    void report (std::ostream& o) const { o << "E!  Removing a non-existent node from the tree." << std::endl; }
  private:
    Tree::Node* offending_node;
  };
  //------------------------------------------------------------------------------------------------------------------
  class NodeInUse : public Exception {
  public:
    NodeInUse (Tree::Node* n) { offending_node = n; }
    ~NodeInUse () {}
    void report (std::ostream& o) const { o << "E!  Adding a node that is already a part of another tree." << std::endl; }
  private:
    Tree::Node* offending_node;
  };
  //------------------------------------------------------------------------------------------------------------------
  class DeletingRootOfNonSingletonTree : public Exception {
  public:
    DeletingRootOfNonSingletonTree (Tree::Node* n) { offending_node = n; }
    ~DeletingRootOfNonSingletonTree () {}
    void report (std::ostream& o) const { o << "E!  Deleting the root node of a non-singleton tree." << std::endl; }
  private:
    Tree::Node* offending_node;
  };
  //------------------------------------------------------------------------------------------------------------------
  class Node {
  public:
    Node () { in_use = false; next_preorder = next_postorder = prev_postorder = 0;  incoming = 0; }
    virtual Node* new_copy () { Node* n = new Node(); copy(n); return n; }
    virtual ~Node () {}
    Node* parent () const { if (incoming != 0) return incoming->source(); else return 0; }
    Node* child (int i) const { if (outgoing[i] != 0) return outgoing[i]->child(); else return 0; }
    Edge* in_edge () const { return incoming; }
    Edge* out_edge (int i) const { return outgoing[i]; }
    int num_children () const { return outgoing.size(); }
    virtual void dump (std::ostream& os) { os << this; }
  protected:
    void copy (Node* n) {}
    Edge* incoming;
    std::deque<Edge*> outgoing;
    Node* next_preorder;
    Node* next_postorder;
    Node* prev_postorder;
    bool in_use;
    friend class Tree;
    friend class Tree::PreOrderIterator;
    friend class Tree::PostOrderIterator;
    friend class Tree::ReversePostOrderIterator;
    friend class Tree::OutEdgesIterator;
    friend class Tree::ChildNodesIterator;
  };
  //------------------------------------------------------------------------------------------------------------------
  class Edge {
  public:
    Edge (Node* _source, Node* _sink) { in_use = false; parent_node = _source; child_node = _sink; }
    virtual Edge* new_copy (Node* _src, Node* _snk) { Edge* e = new Edge(_src, _snk); copy(e); return e; }
    virtual ~Edge () {}
    Node* parent () const { return parent_node; }
    Node* source () const { return parent(); }
    Node* tail () const { return parent(); }
    Node* child () const { return child_node; }
    Node* sink () const { return child(); }
    Node* head () const { return child(); }
    virtual void dump (std::ostream& os) { os << this; }
  protected:
    void copy (Edge* e) {}
    Node* parent_node;
    Node* child_node;
    bool in_use;
    friend class Tree;
    friend class Tree::Node;
  };
  //------------------------------------------------------------------------------------------------------------------
  class NodesIterator : public Iterator {
  public:
    NodesIterator (Tree& t) { tr = &t;  iter = tr->node_set.begin(); }
    ~NodesIterator () {}
    void operator++ () { ++iter; }
    operator bool () { return (iter != tr->node_set.end()); }
    operator Node* () { return *iter; }
    Node* operator -> () { return *iter; }
  protected:
    std::set<Node*>::iterator iter;
    Tree* tr;
  };
  //------------------------------------------------------------------------------------------------------------------
  class EdgesIterator : public Iterator {
  public:
    EdgesIterator (Tree& t) { tr = &t;  iter = tr->edge_set.begin(); }
    ~EdgesIterator () {}
    void operator++ () { ++iter; }
    operator bool () { return (iter != tr->edge_set.end()); }
  protected:
    std::set<Edge*>::iterator iter;
    Tree* tr;
  };
  //------------------------------------------------------------------------------------------------------------------
  class OutEdgesIterator : public Iterator {
  public:
    OutEdgesIterator (Node* n);
    virtual ~OutEdgesIterator () {}
    void operator++ ();
    operator bool () { return (iter != center->outgoing.end()); }
    operator Edge* () { return *iter; }
  private:
    Node* center;
    std::deque<Edge*>::iterator iter;
  };
  //------------------------------------------------------------------------------------------------------------------
  class ChildNodesIterator : private OutEdgesIterator {
  public:
    ChildNodesIterator (Node* n) : OutEdgesIterator(n) {}
    ~ChildNodesIterator () {}
    void operator++ () { OutEdgesIterator::operator++(); }
    operator bool () { return OutEdgesIterator::operator bool(); }
    operator Node* () { Edge* e = (Edge*)(*this);  return e->sink(); }
  };
  //------------------------------------------------------------------------------------------------------------------
  class PreOrderIterator : public Iterator {
  public:
    PreOrderIterator (Tree& t);
    virtual ~PreOrderIterator () {}
    void operator++ () { if (p != 0) p = p->next_preorder; }
    operator bool () { return (p != 0); }
    operator Node* () { return p; }
    Node* operator -> () { return p; }
  private:
    Node* p; // pointer to the last visited node
  };
  //------------------------------------------------------------------------------------------------------------------
  class PostOrderIterator : public Iterator {
  public:
    PostOrderIterator (Tree& t);
    virtual ~PostOrderIterator () {}
    void operator++ () { if (p != 0) p = p->next_postorder; }
    operator bool () { return (p != 0); }
    operator Node* () { return p; }
    Node* operator -> () { return p; }
  private:
    Node* p; // pointer to the last visited node
  };
  //------------------------------------------------------------------------------------------------------------------
  class ReversePostOrderIterator : public Iterator {
  public:
    ReversePostOrderIterator (Tree& t);
    virtual ~ReversePostOrderIterator () {}
    void operator++ () { if (p != 0) p = p->prev_postorder; }
    operator bool() { return (p != 0); }
    operator Node* () { return p; }
    Node* operator -> () { return p; }
  private:
    Node* p; // pointer to the last visited node
  };
  //------------------------------------------------------------------------------------------------------------------
  Tree () { root_node = 0; }
  Tree (Node* root) { root_node = 0; add(root); }
  virtual ~Tree () {}

  Node* getRoot () { return root_node; }

  void add (Edge*) throw (DuplicateEdge, EdgeInUse, EmptyEdge, SecondParent, EmptyEndPoint);
  void add (Node*) throw (DuplicateNode, NodeInUse, EmptyNode);
  void add_empty_edge (Node*) throw (EmptyNode);
  void remove (Edge*) throw (NonexistentEdge, EmptyEdge);
  void remove (Node*) throw (NonexistentNode, DeletingRootOfNonSingletonTree, EmptyNode);
  Node* clone (Node*);

protected:
  Node* root_node;
  std::set<Node*> node_set;
  std::set<Edge*> edge_set;
  bool preorder_needed;
  bool postorder_needed;
  bool rpostorder_needed;

private:
  Node* create_preorder_links (Node*);
  Node* create_postorder_links (Node*);
  Node* create_rpostrder_links (Node*);
};
//--------------------------------------------------------------------------------------------------------------------

#endif