Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
graph.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 //  Generic graph library
00037 //
00038 //   It consists three components:
00039 //     -- a graph container,
00040 //     -- a definition of graph iterator,
00041 //     -- and algorithms accessing using only the graph iterator.
00042 //
00043 //
00044 //  Graph Container:
00045 //
00046 //   digraph<NODE, EDGE> --  a directed graph of NODE and EDGE.
00047 //     node/edge are shorthand for digraph<NODE,EDGE>::node,
00048 //     and digraph<NODE,EDGE>::edge respectively.
00049 //     
00050 //     node *add_node() -- add a uninitialized node to the directed graph.
00051 //     node *add_node(NODE v) -- add a node to the directed graph.
00052 //     edge *add_edge(node *tail, node *head) -- add an edge (tail, head) to the graph.
00053 //     void delete_edge(edge *e) -- delete an edge.
00054 //     void delete_node(node *n) -- delete a node.
00055 //     void delete_node_and_edge(node *n) -- delete a node and its succ/pred edges.
00056 //
00057 //     node_set_iter  -- iterates all nodes in the graph
00058 //     succ_node_iter -- successor node forward iterator 
00059 //     succ_edge_iter -- successor edge forward iterator 
00060 //     pred_node_iter -- predecessor node forward iterator
00061 //     pred_edge_iter -- predecessor edge forward iterator
00062 //
00063 //     node_set_iter node_set_begin() -- returns an iterator pointing at the
00064 //          beginning of the node set sequence.
00065 //     node_set_iter node_set_end() -- returns an iterator pointing at the
00066 //          end of the node set sequence.
00067 //
00068 //     succ_node_iter succ_node_begin(node *v) 
00069 //         -- returns the beginning of the successor node* sequence.
00070 //     succ_node_iter succ_node_end(node *v)
00071 //         -- returns the end of the successor node* sequence.
00072 //
00073 //      similiar definitions for {succ,pred}_{node,edge}_{begin,end}().
00074 //
00075 //   digraph<NODE, EDGE>::edge
00076 //      node *head();  // the head node of the edge
00077 //      node *tail();  // the tail node of the edge
00078 //
00079 //
00080 //  Graph Iterator :
00081 //
00082 //    The graph iterator is the interface between the graph container and
00083 //    the graph algorithms.   The iterator is indeed a graph node.
00084 // 
00085 //    It could be divided into several classes: 
00086 //      node_graph_iterator, node_edge_graph_iterator
00087 //
00088 //    Operations defined on the node_graph iterator:
00089 //      succ_node_begin(), succ_node_end(),
00090 //      pred_node_begin(), pred_node_end().
00091 //
00092 //    Operations defined on the node_edge_graph iterator,
00093 //    in addition to the on supported by node_graph iterator:
00094 //      succ_edge_begin(), succ_edge_end(),
00095 //      pred_edge_begin(), pred_edge_end().
00096 //
00097 //
00098 //  Graph Algorithms:
00099 //
00100 //   directed graph Traversal:
00101 //     preorder_iter<GRAPH, ITERATOR, VISITED>
00102 //     postorder_iter<GRAPH, ITERATOR, VISITED>
00103 //     depth_first_iter<GRAPH, ITERATOR, VISITED>
00104 //     breath_first_iter<GRAPH, ITERATOR, VISITED>
00105 //    
00106 //       where ITERATOR contains the direction of graph traversal.
00107 //       If ITERATOR is pred_node_iter, it performs the traversal on G as if
00108 //       it is traversaling a graph G' where edges in G' are inverted edges from G.
00109 //
00110 //       where VISITED is a set keeping track of the state of the traversal.
00111 //       (the set of nodes have been visited).  The default is set<GRAPH::node*>.
00112 //       It could be replaced using a bitset of bool vector if there is a unique-id
00113 //       associated with each node*.
00114 //
00115 //     dep_order_iter<GRAPH, SUCC_ITERATOR, PRED_ITERATOR, VISITED>
00116 //       1. a node is made ready after all of its successor are visited or
00117 //          it has no succ.
00118 //       2. ready nodes are processed in FIFO order.
00119 //       Note that the order is defined for a DAG, but not defined for cyclic graph.
00120 //
00121 //   tree Traversal:
00122 //     preorder_tree_iter<TREE, ITERATOR>
00123 //     postorder_tree_iter<TREE, ITERATOR>
00124 //     depth_first_tree_iter<TREE, ITERATOR>
00125 //     breath_first_tree_iter<TREE, ITERATOR>
00126 //
00127 //  TO DO:
00128 //   * add allocator
00129 //   * decide if succ_node_begin() and succ_node_end() should be
00130 //     a member function of digraph or node.
00131 //   * complete the iterators: traits, ...
00132 //   * implement dominator tree algorithm.
00133 //   
00134 //   
00135 
00136 #ifndef __GRAPH_H
00137 #define __GRAPH_H
00138 
00139 #include <hash_set.h>
00140 #include <vector.h>
00141 #include <stack.h>
00142 #include <bvector.h>
00143 #include <set.h>
00144 
00145 template <class NODE, class EDGE> struct digraph_node;
00146 template <class NODE, class EDGE> struct digraph_edge;
00147 template <class NODE, class EDGE> struct digraph;
00148 template <class DIGRAPH> struct succ_node_iter;
00149 template <class DIGRAPH> struct succ_edge_iter;
00150 template <class DIGRAPH> struct pred_node_iter;
00151 template <class DIGRAPH> struct pred_edge_iter;
00152 
00153 
00154 template <class NODE, class EDGE>
00155 struct digraph_edge {
00156   typedef digraph_node<NODE, EDGE> digraph_node;
00157 
00158   EDGE edge;
00159   digraph_node *head;
00160   digraph_node *tail;
00161   digraph_edge *next_succ;
00162   digraph_edge *next_pred;
00163 
00164   digraph_edge<NODE, EDGE>(digraph_node *v, digraph_node *w) : 
00165     tail(v),head(w),next_succ(0),next_pred(0),edge() {}
00166 };
00167 
00168 
00169 template <class NODE, class EDGE>
00170 struct digraph_node {
00171   typedef digraph_edge<NODE, EDGE> digraph_edge;
00172   typedef digraph<NODE, EDGE>      digraph;
00173   typedef succ_node_iter<digraph>  succ_node_iter;
00174   typedef pred_node_iter<digraph>  pred_node_iter;
00175 
00176   NODE node;
00177   int n_succ;
00178   int n_pred;
00179   digraph_edge *first_succ;
00180   digraph_edge *first_pred;
00181 
00182   void add_succ(digraph_edge *e) { ++n_succ; e->next_succ = first_succ; first_succ = e; }
00183   void add_pred(digraph_edge *e) { ++n_pred; e->next_pred = first_pred; first_pred = e; }
00184 
00185   void delete_succ_edge(digraph_edge *e) {
00186     if (first_succ == e) {
00187       e = e->next_succ;
00188       return;
00189     }
00190     for (digraph_edge *t = e; t->next_succ != e; t = t->next_succ);
00191     if (t->next_succ == e)
00192       t->next_succ = e->next_succ;
00193   }
00194 
00195   void delete_pred_edge(digraph_edge *e) {
00196     if (first_pred == e) {
00197       e = e->next_pred;
00198       return;
00199     }
00200     for (digraph_edge *t = e; t->next_pred != e; t = t->next_pred);
00201     if (t->next_pred == e)
00202       t->next_pred = e->next_pred;
00203   }
00204 
00205   succ_node_iter succ_node_begin() const
00206     { succ_node_iter s; s.cur = first_succ; return s; }
00207   
00208   succ_node_iter succ_node_end()   const
00209     { succ_node_iter s; s.cur = 0; return s; }
00210 
00211   pred_node_iter pred_node_begin() const
00212     { pred_node_iter s; s.cur = first_pred; return s; }
00213 
00214   pred_node_iter pred_node_end()   const 
00215     { pred_node_iter s; s.cur = 0; return s; }
00216 
00217   digraph_node<NODE, EDGE>(NODE v) { 
00218     node = v; n_succ = n_pred = 0;  first_succ = first_pred = 0; }
00219 
00220   digraph_node<NODE, EDGE>() { 
00221     n_succ = n_pred = 0;  first_succ = first_pred = 0; }
00222 };
00223 
00224 
00225 template <class X>
00226 struct ptr_hash
00227 {
00228  size_t operator()(const X* s) const { return reinterpret_cast<size_t>(s); }
00229 };
00230 
00231 template <class NODE, class EDGE>
00232 struct digraph {
00233   typedef digraph<NODE, EDGE>          self;
00234   typedef digraph_node<NODE, EDGE>     node;
00235   typedef digraph_edge<NODE, EDGE>     edge;
00236   typedef succ_edge_iter<self>         succ_edge_iter;
00237   typedef succ_node_iter<self>         succ_node_iter;
00238   typedef pred_edge_iter<self>         pred_edge_iter;
00239   typedef pred_node_iter<self>         pred_node_iter;
00240   typedef hash_set<node*, ptr_hash<node> >  node_set_type;
00241   typedef node_set_type::iterator    node_set_iter;
00242 
00243   node_set_type  node_set;
00244   
00245   node_set_iter node_set_begin() { return node_set.begin(); }
00246   node_set_iter node_set_end()   { return node_set.end(); }
00247 
00248   node *add_node(NODE v) {
00249     node *p = new node(v);
00250     node_set.insert(p);
00251     return p;
00252   }
00253 
00254   node *add_node() {
00255     node *p = new node();
00256     node_set.insert(p);
00257     return p;
00258   }
00259 
00260   edge *add_edge(node *v, node *w) {
00261     edge *e = new edge(v, w);
00262     v->add_succ(e);
00263     w->add_pred(e);
00264     return e;
00265   }
00266 
00267   void delete_edge(edge *e) {
00268     e->tail->delete_succ_edge(e);
00269     e->head->delete_pred_edge(e);
00270     delete e;
00271   }
00272 
00273   void delete_node(node *v) {
00274     node_set.erase(v);
00275     delete v;
00276   }
00277 
00278   void delete_node_and_edge(node *v) {
00279     while (v->first_succ) 
00280       v->delete_succ_edge(v->first_succ);
00281     while (v->first_pred) 
00282       v->delete_succ_edge(v->first_pred);
00283     delete_node(v);
00284   }
00285 
00286   edge *find_edge(node *v, node *w);
00287   node *head(edge *e);
00288   node *tail(edge *e);
00289 
00290   succ_node_iter succ_node_begin(node *v) const
00291     { succ_node_iter s; s.cur = v->first_succ; return s; }
00292 
00293   succ_node_iter succ_node_end(node *v)   const
00294     { succ_node_iter s; s.cur = 0; return s; }
00295 
00296   pred_node_iter pred_node_begin(node *v) const
00297     { pred_node_iter s; s.cur = v->first_succ; return s; }
00298 
00299   pred_node_iter pred_node_end(node *v)   const 
00300     { pred_node_iter s; s.cur = 0; return s; }
00301 
00302   succ_edge_iter succ_edge_begin(node *v) const
00303     { succ_edge_iter s; s.cur = v->first_succ; return s; }
00304 
00305   succ_edge_iter succ_edge_end(node *v)   const
00306     { succ_edge_iter s; s.cur = 0; return s; }
00307 
00308   pred_edge_iter pred_edge_begin(node *v) const
00309     { pred_edge_iter s; s.cur = v->first_succ; return s; }
00310 
00311   pred_edge_iter pred_edge_end(node *v)   const 
00312     { pred_edge_iter s; s.cur = 0; return s; }
00313 };
00314 
00315 
00316 
00317 template <class DIGRAPH>
00318 struct succ_node_iter {
00319   typedef DIGRAPH::node node;
00320   typedef DIGRAPH::edge edge;
00321   typedef succ_node_iter<DIGRAPH> self;
00322 
00323   edge *cur;
00324 
00325   self operator ++(int) { self tmp = *this; cur = cur->next_succ; return tmp; }
00326   self &operator ++() { cur = cur->next_succ; return *this; }
00327   node *operator *() { return cur->head; }
00328   friend bool operator ==(const self& x, const self& y) { return x.cur == y.cur; }
00329 
00330   self begin(node *v) const { self s; s.cur = v->first_succ; return s; }
00331   self end(node *v)   const { self s; s.cur = 0; return s; }
00332 };
00333 
00334 
00335 template <class DIGRAPH>
00336 struct succ_edge_iter {
00337   typedef DIGRAPH::node node;
00338   typedef DIGRAPH::edge edge;
00339   typedef succ_edge_iter<DIGRAPH> self;
00340 
00341   edge *cur;
00342 
00343   self operator ++(int) { self tmp = *this; cur = cur->next_succ; return tmp; }
00344   self& operator ++() { cur = cur->next_succ; return *this; }
00345   edge *operator *() { return cur; }
00346   friend bool operator ==(const self& x, const self& y) { return x.cur == y.cur; }
00347 
00348   self begin(node *v) const { self s; s.cur = v->first_succ; return s; }
00349   self end(node *v)   const { self s; s.cur = 0; return s; }
00350 };
00351 
00352 
00353 template <class DIGRAPH>
00354 struct pred_node_iter {
00355   typedef DIGRAPH::node node;
00356   typedef DIGRAPH::edge edge;
00357   typedef pred_node_iter<DIGRAPH> self;
00358 
00359   edge *cur;
00360 
00361   self operator ++(int) { self tmp = *this; cur = cur->next_pred; return tmp; }
00362   self& operator ++() { cur = cur->next_pred; return *this; }
00363   node *operator *() { return cur->tail; }
00364   friend bool operator ==(const self& x, const self& y) { return x.cur == y.cur; }
00365 
00366   self begin(node *v) const { self s; s.cur = v->first_pred; return s; }
00367   self end(node *v)   const { self s; s.cur = 0; return s; }
00368 };
00369 
00370 
00371 template <class DIGRAPH>
00372 struct pred_edge_iter {
00373   typedef DIGRAPH::node node;
00374   typedef DIGRAPH::edge edge;
00375   typedef pred_edge_iter<DIGRAPH> self;
00376 
00377   edge *cur;
00378 
00379   self operator ++(int) { self tmp = *this; cur = cur->next_pred; return tmp; }
00380   self& operator ++() { cur = cur->next_pred; return *this; }
00381   edge *operator *() { return cur; }
00382   friend bool operator ==(const self& x, const self& y) { return x.cur == y.cur; }
00383 
00384   self begin(node *v) const { self s; s.cur = v->first_pred; return s; }
00385   self end(node *v)   const { self s; s.cur = 0; return s; }
00386 };
00387 
00388 
00389 //  preorder graph iterator
00390 template <class GRAPH, class ITERATOR = GRAPH::succ_node_iter, class VISITED = set<GRAPH::node*> >
00391 struct preorder_iter {
00392   typedef preorder_iter<GRAPH, ITERATOR, VISITED> self;
00393   stack<ITERATOR>  state;
00394   VISITED visited_set;
00395 
00396   ITERATOR cur;
00397 
00398   bool visited(GRAPH::node *v) { return visited_set.find(v) != visited_set.end(); }
00399   void set_visited(GRAPH::node *v) { visited_set.insert(v); }
00400 
00401   self &operator ++() { 
00402     GRAPH::node *n = *cur;
00403     if (cur.begin(n) != cur.end(n)) {
00404       ITERATOR t = cur.begin(n);
00405       while (t != t.end(0) && visited(*t))
00406         ++t;
00407       if (t != t.end(0)) {
00408         set_visited(*t);
00409         ++cur;
00410         state.push(cur);
00411         cur = t;
00412         return *this;
00413       }
00414     }
00415     ++cur;
00416     while (true) {
00417       while (cur != cur.end(0) && visited(*cur)) 
00418         ++cur;
00419       if (cur != cur.end(0)) break;
00420       while (cur == cur.end(0) && !state.empty()) {
00421         cur = state.top();
00422         state.pop();
00423       }
00424       if (cur == cur.end(0)) break;
00425     }
00426     if (cur != cur.end(0))
00427       set_visited(*cur);
00428     return *this; 
00429   }
00430   self operator ++(int) { self tmp = *this; ++cur; return tmp; }
00431   void set_cur(GRAPH::node *v) { 
00432     cur.cur = new GRAPH::edge(v,v); 
00433     set_visited(*cur);
00434   }
00435   bool empty() { return cur == cur.end(0); }
00436   GRAPH::node *operator *() { return *cur; }
00437   
00438   preorder_iter<GRAPH, ITERATOR, VISITED>() {}; 
00439   preorder_iter<GRAPH, ITERATOR, VISITED>(GRAPH::node *v) { set_cur(v); };
00440 };
00441 
00442 
00443 template <class GRAPH, class ITERATOR = GRAPH::succ_node_iter, class VISITED = set<GRAPH::node*> >
00444 struct postorder_iter {
00445   typedef postorder_iter<GRAPH, ITERATOR, VISITED> self;
00446   stack<ITERATOR>  state;
00447   VISITED visited_set;
00448 
00449   ITERATOR cur;
00450   
00451   bool visited(GRAPH::node *v) { return visited_set.find(v) != visited_set.end(); }
00452   void set_visited(GRAPH::node *v) { visited_set.insert(v); }
00453 
00454   self &operator ++() { 
00455     ++cur;
00456     while (cur != cur.end(0) && visited(*cur)) 
00457       ++cur;
00458     if (cur == cur.end(0)) {
00459       if (!state.empty()) {
00460         cur = state.top();
00461         state.pop();
00462         return *this;
00463       }
00464     } else {
00465       GRAPH::node *n = *cur;
00466       while (cur.begin(n) != cur.end(n)) {
00467         ITERATOR t = cur.begin(n);
00468         while (t != t.end(0) && visited(*t))
00469           ++t;
00470         if (t != t.end(0)) {
00471           set_visited(*t);
00472           set_visited(*cur);
00473           state.push(cur);
00474           cur = t;
00475         } else
00476           break;
00477         n = *cur;
00478       }
00479     }
00480     if (cur != cur.end(0))
00481       set_visited(*cur);
00482     return *this; 
00483   }
00484   self operator ++(int) { self tmp = *this; ++cur; return tmp; }
00485   void set_cur(GRAPH::node *v) { 
00486     cur.cur = new GRAPH::edge(v,v); 
00487     GRAPH::node *n = *cur;
00488     set_visited(v);
00489     while (cur.begin(n) != cur.end(n)) {
00490       ITERATOR t = cur.begin(n);
00491       while (t != t.end(0) && visited(*t))
00492         ++t;
00493       if (t != t.end(0)) {
00494         set_visited(*t);
00495         set_visited(*cur);
00496         state.push(cur);
00497         cur = t;
00498       } else
00499         break;
00500       n = *cur;
00501     }
00502     if (cur != cur.end(0))
00503       set_visited(*cur);
00504   }
00505   bool empty() { return cur == cur.end(0); }
00506   GRAPH::node *operator *() { return *cur; }
00507 
00508   postorder_iter<GRAPH, ITERATOR, VISITED>() {}; 
00509   postorder_iter<GRAPH, ITERATOR, VISITED>(GRAPH::node *v) { set_cur(v); };
00510 };
00511 
00512 
00513 template <class GRAPH, class ITERATOR = GRAPH::succ_node_iter, class VISITED = set<GRAPH::node*> >
00514 struct depth_first_iter : preorder_iter<GRAPH, ITERATOR, VISITED> {
00515   depth_first_iter<GRAPH, ITERATOR, VISITED>(GRAPH::node *v) { set_cur(v); };
00516 };
00517 
00518 
00519 template <class GRAPH, class ITERATOR = GRAPH::succ_node_iter, class VISITED = set<GRAPH::node*> >
00520 struct breath_first_iter {
00521   typedef breath_first_iter<GRAPH, ITERATOR, VISITED> self;
00522   deque<ITERATOR>  state;
00523   VISITED visited_set;
00524 
00525   bool visited(GRAPH::node *v) { return visited_set.find(v) != visited_set.end(); }
00526   void set_visited(GRAPH::node *v) { visited_set.insert(v); }
00527 
00528   self &operator ++() { 
00529     if (state.empty()) return *this;
00530     ITERATOR cur = state.front();
00531     state.pop_front();
00532     ITERATOR t;
00533     GRAPH::node *n = *cur;
00534     for (t = cur.begin(n); t != cur.end(n); ++t) {
00535       if (!visited(*t)) {
00536         state.push_back(t);
00537         set_visited(*t);
00538       }
00539     }
00540     return *this; 
00541   }
00542   self operator ++(int) { self tmp = *this; ++cur; return tmp; }
00543   void set_cur(GRAPH::node *v) { 
00544     ITERATOR t;
00545     t.cur = new GRAPH::edge(v,v); 
00546     set_visited(*t);
00547     state.push_back(t);
00548   }
00549   bool empty() { return state.empty(); }
00550   GRAPH::node *operator *() { return *(state.front()); }
00551 
00552   breath_first_iter<GRAPH, ITERATOR, VISITED>() {}; 
00553   breath_first_iter<GRAPH, ITERATOR, VISITED>(GRAPH::node *v) { set_cur(v); };
00554 };
00555 
00556 
00557 template <class GRAPH,
00558    class SUCC_ITERATOR = GRAPH::succ_node_iter, 
00559    class PRED_ITERATOR = GRAPH::pred_node_iter, 
00560    class VISITED = set<GRAPH::node*> >
00561 struct dep_order_iter {
00562   typedef dep_order_iter<GRAPH, SUCC_ITERATOR, PRED_ITERATOR, VISITED> self;
00563   deque<GRAPH::node *> state;
00564   VISITED visited_set;
00565 
00566   bool visited(GRAPH::node *v) { return visited_set.find(v) != visited_set.end(); }
00567   void set_visited(GRAPH::node *v) { visited_set.insert(v); }
00568 
00569 private:
00570   bool all_succ_visited(GRAPH::node *n) {
00571     SUCC_ITERATOR t;
00572     for (t = n->succ_node_begin(); t != n->succ_node_end(); ++t) {
00573       if (!visited(*t))
00574         return false;
00575     }
00576     return true;
00577   }
00578 
00579 public:
00580 
00581   self &operator ++() { 
00582     if (state.empty()) return *this;
00583     GRAPH::node *n = state.front();
00584     state.pop_front();
00585     set_visited(n);
00586 
00587     PRED_ITERATOR t;
00588     for (t = n->pred_node_begin(); t != n->pred_node_end(); ++t) {
00589       if (!visited(*t) && all_succ_visited(*t)) {
00590         state.push_back(*t);
00591         set_visited(*t);
00592       }
00593     }
00594     return *this; 
00595   }
00596   self operator ++(int) { self tmp = *this; ++cur; return tmp; }
00597   bool empty() { return state.empty(); }
00598   GRAPH::node *operator *() { return state.front(); }
00599 
00600   void make_ready(GRAPH::node *n) {
00601     state.push_back(n);
00602     set_visited(n);
00603   }
00604 
00605   dep_order_iter<GRAPH, SUCC_ITERATOR, PRED_ITERATOR, VISITED>(GRAPH *g) { 
00606     GRAPH::node_set_iter iter;
00607     for (iter = g->node_set_begin(); iter != g->node_set_end(); ++iter) {
00608       if (all_succ_visited(*iter)) {
00609         state.push_back(*iter);
00610         set_visited(*iter);
00611       }
00612     }
00613   }
00614 };
00615 
00616 
00617 template <class TREE>
00618 struct never_visited {
00619   TREE::node *find(TREE::node *n) { return 0; }
00620   TREE::node *end() { return 0; }
00621   void insert(TREE::node *n) { }
00622 };
00623 
00624 
00625 template <class TREE, class ITERATOR>
00626 struct preorder_tree_iter :
00627 preorder_iter<TREE, ITERATOR, never_visited<TREE> > {};
00628 
00629 template <class TREE, class ITERATOR>
00630 struct postorder_tree_iter :
00631 postorder_iter<TREE, ITERATOR, never_visited<TREE> > {};
00632 
00633 template <class TREE, class ITERATOR>
00634 struct depth_first_tree_iter :
00635 depth_first_iter<TREE, ITERATOR, never_visited<TREE> > {};
00636 
00637 template <class TREE, class ITERATOR>
00638 struct breath_first_tree_iter :
00639 breath_first_iter<TREE, ITERATOR, never_visited<TREE> > {};
00640 
00641 
00642 #endif  /* __GRAPH_H */
00643 
00644 // Local Variables:
00645 // mode:C++
00646 // End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines