Create a new #include "Support/..." directory structure to move things
[oota-llvm.git] / include / llvm / ADT / DepthFirstIterator.h
1 //===- Support/DepthFirstIterator.h - Depth First iterator -------*- C++ -*--=//
2 //
3 // This file builds on the Support/GraphTraits.h file to build generic depth
4 // first graph iterator.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_SUPPORT_DEPTH_FIRST_ITERATOR_H
9 #define LLVM_SUPPORT_DEPTH_FIRST_ITERATOR_H
10
11 #include "Support/GraphTraits.h"
12 #include <iterator>
13 #include <stack>
14 #include <set>
15
16 // Generic Depth First Iterator
17 template<class GraphT, class GT = GraphTraits<GraphT> >
18 class df_iterator : public std::forward_iterator<typename GT::NodeType,
19                                                  ptrdiff_t> {
20   typedef typename GT::NodeType          NodeType;
21   typedef typename GT::ChildIteratorType ChildItTy;
22
23   set<NodeType *>   Visited;    // All of the blocks visited so far...
24   // VisitStack - Used to maintain the ordering.  Top = current block
25   // First element is node pointer, second is the 'next child' to visit
26   stack<pair<NodeType *, ChildItTy> > VisitStack;
27   const bool Reverse;         // Iterate over children before self?
28 private:
29   void reverseEnterNode() {
30     pair<NodeType *, ChildItTy> &Top = VisitStack.top();
31     NodeType *Node = Top.first;
32     ChildItTy &It  = Top.second;
33     for (; It != GT::child_end(Node); ++It) {
34       NodeType *Child = *It;
35       if (!Visited.count(Child)) {
36         Visited.insert(Child);
37         VisitStack.push(make_pair(Child, GT::child_begin(Child)));
38         reverseEnterNode();
39         return;
40       }
41     }
42   }
43
44   inline df_iterator(NodeType *Node, bool reverse) : Reverse(reverse) {
45     Visited.insert(Node);
46     VisitStack.push(make_pair(Node, GT::child_begin(Node)));
47     if (Reverse) reverseEnterNode();
48   }
49   inline df_iterator() { /* End is when stack is empty */ }
50
51 public:
52   typedef df_iterator<GraphT, GT> _Self;
53
54   // Provide static begin and end methods as our public "constructors"
55   static inline _Self begin(GraphT G, bool Reverse = false) {
56     return _Self(GT::getEntryNode(G), Reverse);
57   }
58   static inline _Self end(GraphT G) { return _Self(); }
59
60
61   inline bool operator==(const _Self& x) const { 
62     return VisitStack == x.VisitStack;
63   }
64   inline bool operator!=(const _Self& x) const { return !operator==(x); }
65
66   inline pointer operator*() const { 
67     return VisitStack.top().first;
68   }
69
70   // This is a nonstandard operator-> that dereferences the pointer an extra
71   // time... so that you can actually call methods ON the Node, because
72   // the contained type is a pointer.  This allows BBIt->getTerminator() f.e.
73   //
74   inline NodeType *operator->() const { return operator*(); }
75
76   inline _Self& operator++() {   // Preincrement
77     if (Reverse) {               // Reverse Depth First Iterator
78       if (VisitStack.top().second == GT::child_end(VisitStack.top().first))
79         VisitStack.pop();
80       if (!VisitStack.empty())
81         reverseEnterNode();
82     } else {                     // Normal Depth First Iterator
83       do {
84         pair<NodeType *, ChildItTy> &Top = VisitStack.top();
85         NodeType *Node = Top.first;
86         ChildItTy &It  = Top.second;
87
88         while (It != GT::child_end(Node)) {
89           NodeType *Next = *It++;
90           if (!Visited.count(Next)) {  // Has our next sibling been visited?
91             // No, do it now.
92             Visited.insert(Next);
93             VisitStack.push(make_pair(Next, GT::child_begin(Next)));
94             return *this;
95           }
96         }
97         
98         // Oops, ran out of successors... go up a level on the stack.
99         VisitStack.pop();
100       } while (!VisitStack.empty());
101     }
102     return *this; 
103   }
104
105   inline _Self operator++(int) { // Postincrement
106     _Self tmp = *this; ++*this; return tmp; 
107   }
108
109   // nodeVisited - return true if this iterator has already visited the
110   // specified node.  This is public, and will probably be used to iterate over
111   // nodes that a depth first iteration did not find: ie unreachable nodes.
112   //
113   inline bool nodeVisited(NodeType *Node) const { 
114     return Visited.count(Node) != 0;
115   }
116 };
117
118
119 // Provide global constructors that automatically figure out correct types...
120 //
121 template <class T>
122 df_iterator<T> df_begin(T G, bool Reverse = false) {
123   return df_iterator<T>::begin(G, Reverse);
124 }
125
126 template <class T>
127 df_iterator<T> df_end(T G) {
128   return df_iterator<T>::end(G);
129 }
130
131 // Provide global definitions of inverse depth first iterators...
132 template <class T>
133 struct idf_iterator : public df_iterator<Inverse<T> > {
134   idf_iterator(const df_iterator<Inverse<T> > &V) :df_iterator<Inverse<T> >(V){}
135 };
136
137 template <class T>
138 idf_iterator<T> idf_begin(T G, bool Reverse = false) {
139   return idf_iterator<T>::begin(G, Reverse);
140 }
141
142 template <class T>
143 idf_iterator<T> idf_end(T G){
144   return idf_iterator<T>::end(G);
145 }
146
147 #endif