1 //===- llvm/unittest/ADT/TestGraph.h - Graph for testing ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Common graph data structure for testing.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/GraphTraits.h"
19 #ifndef LLVM_UNITTESTS_ADT_TEST_GRAPH_H
20 #define LLVM_UNITTESTS_ADT_TEST_GRAPH_H
24 /// Graph<N> - A graph with N nodes. Note that N can be at most 8.
30 Graph
& operator=(const Graph
&);
32 static void ValidateIndex(unsigned Idx
) {
33 assert(Idx
< N
&& "Invalid node index!");
37 /// NodeSubset - A subset of the graph's nodes.
39 typedef unsigned char BitVector
; // Where the limitation N <= 8 comes from.
41 NodeSubset(BitVector e
) : Elements(e
) {}
43 /// NodeSubset - Default constructor, creates an empty subset.
44 NodeSubset() : Elements(0) {
45 assert(N
<= sizeof(BitVector
)*CHAR_BIT
&& "Graph too big!");
48 /// Comparison operators.
49 bool operator==(const NodeSubset
&other
) const {
50 return other
.Elements
== this->Elements
;
52 bool operator!=(const NodeSubset
&other
) const {
53 return !(*this == other
);
56 /// AddNode - Add the node with the given index to the subset.
57 void AddNode(unsigned Idx
) {
59 Elements
|= 1U << Idx
;
62 /// DeleteNode - Remove the node with the given index from the subset.
63 void DeleteNode(unsigned Idx
) {
65 Elements
&= ~(1U << Idx
);
68 /// count - Return true if the node with the given index is in the subset.
69 bool count(unsigned Idx
) {
71 return (Elements
& (1U << Idx
)) != 0;
74 /// isEmpty - Return true if this is the empty set.
75 bool isEmpty() const {
79 /// isSubsetOf - Return true if this set is a subset of the given one.
80 bool isSubsetOf(const NodeSubset
&other
) const {
81 return (this->Elements
| other
.Elements
) == other
.Elements
;
84 /// Complement - Return the complement of this subset.
85 NodeSubset
Complement() const {
86 return ~(unsigned)this->Elements
& ((1U << N
) - 1);
89 /// Join - Return the union of this subset and the given one.
90 NodeSubset
Join(const NodeSubset
&other
) const {
91 return this->Elements
| other
.Elements
;
94 /// Meet - Return the intersection of this subset and the given one.
95 NodeSubset
Meet(const NodeSubset
&other
) const {
96 return this->Elements
& other
.Elements
;
100 /// NodeType - Node index and set of children of the node.
101 typedef std::pair
<unsigned, NodeSubset
> NodeType
;
104 /// Nodes - The list of nodes for this graph.
108 /// Graph - Default constructor. Creates an empty graph.
110 // Let each node know which node it is. This allows us to find the start of
111 // the Nodes array given a pointer to any element of it.
112 for (unsigned i
= 0; i
!= N
; ++i
)
116 /// AddEdge - Add an edge from the node with index FromIdx to the node with
118 void AddEdge(unsigned FromIdx
, unsigned ToIdx
) {
119 ValidateIndex(FromIdx
);
120 Nodes
[FromIdx
].second
.AddNode(ToIdx
);
123 /// DeleteEdge - Remove the edge (if any) from the node with index FromIdx to
124 /// the node with index ToIdx.
125 void DeleteEdge(unsigned FromIdx
, unsigned ToIdx
) {
126 ValidateIndex(FromIdx
);
127 Nodes
[FromIdx
].second
.DeleteNode(ToIdx
);
130 /// AccessNode - Get a pointer to the node with the given index.
131 NodeType
*AccessNode(unsigned Idx
) const {
133 // The constant cast is needed when working with GraphTraits, which insists
134 // on taking a constant Graph.
135 return const_cast<NodeType
*>(&Nodes
[Idx
]);
138 /// NodesReachableFrom - Return the set of all nodes reachable from the given
140 NodeSubset
NodesReachableFrom(unsigned Idx
) const {
141 // This algorithm doesn't scale, but that doesn't matter given the small
142 // size of our graphs.
143 NodeSubset Reachable
;
145 // The initial node is reachable.
146 Reachable
.AddNode(Idx
);
148 NodeSubset
Previous(Reachable
);
150 // Add in all nodes which are children of a reachable node.
151 for (unsigned i
= 0; i
!= N
; ++i
)
152 if (Previous
.count(i
))
153 Reachable
= Reachable
.Join(Nodes
[i
].second
);
155 // If nothing changed then we have found all reachable nodes.
156 if (Reachable
== Previous
)
163 /// ChildIterator - Visit all children of a node.
164 class ChildIterator
{
167 /// FirstNode - Pointer to first node in the graph's Nodes array.
169 /// Children - Set of nodes which are children of this one and that haven't
170 /// yet been visited.
173 ChildIterator(); // Disable default constructor.
175 ChildIterator(NodeType
*F
, NodeSubset C
) : FirstNode(F
), Children(C
) {}
178 /// ChildIterator - Copy constructor.
179 ChildIterator(const ChildIterator
& other
) : FirstNode(other
.FirstNode
),
180 Children(other
.Children
) {}
182 /// Comparison operators.
183 bool operator==(const ChildIterator
&other
) const {
184 return other
.FirstNode
== this->FirstNode
&&
185 other
.Children
== this->Children
;
187 bool operator!=(const ChildIterator
&other
) const {
188 return !(*this == other
);
191 /// Prefix increment operator.
192 ChildIterator
& operator++() {
193 // Find the next unvisited child node.
194 for (unsigned i
= 0; i
!= N
; ++i
)
195 if (Children
.count(i
)) {
196 // Remove that child - it has been visited. This is the increment!
197 Children
.DeleteNode(i
);
200 assert(false && "Incrementing end iterator!");
201 return *this; // Avoid compiler warnings.
204 /// Postfix increment operator.
205 ChildIterator
operator++(int) {
206 ChildIterator
Result(*this);
211 /// Dereference operator.
212 NodeType
*operator*() {
213 // Find the next unvisited child node.
214 for (unsigned i
= 0; i
!= N
; ++i
)
215 if (Children
.count(i
))
216 // Return a pointer to it.
217 return FirstNode
+ i
;
218 assert(false && "Dereferencing end iterator!");
219 return nullptr; // Avoid compiler warning.
223 /// child_begin - Return an iterator pointing to the first child of the given
225 static ChildIterator
child_begin(NodeType
*Parent
) {
226 return ChildIterator(Parent
- Parent
->first
, Parent
->second
);
229 /// child_end - Return the end iterator for children of the given node.
230 static ChildIterator
child_end(NodeType
*Parent
) {
231 return ChildIterator(Parent
- Parent
->first
, NodeSubset());
235 template <unsigned N
>
236 struct GraphTraits
<Graph
<N
> > {
237 typedef typename Graph
<N
>::NodeType
*NodeRef
;
238 typedef typename Graph
<N
>::ChildIterator ChildIteratorType
;
240 static NodeRef
getEntryNode(const Graph
<N
> &G
) { return G
.AccessNode(0); }
241 static ChildIteratorType
child_begin(NodeRef Node
) {
242 return Graph
<N
>::child_begin(Node
);
244 static ChildIteratorType
child_end(NodeRef Node
) {
245 return Graph
<N
>::child_end(Node
);
249 } // End namespace llvm