1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines the little GraphTraits<X> template class that should be
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// specialized by classes that want to be iteratable by generic graph iterators.
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file also defines the marker class Inverse that is used to iterate over
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// graphs in a graph defined, inverse ordering...
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef LLVM_ADT_GRAPHTRAITS_H
19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define LLVM_ADT_GRAPHTRAITS_H
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace llvm {
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// GraphTraits - This class should be specialized by different graph types...
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// which is why the default version is empty.
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<class GraphType>
27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct GraphTraits {
28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Elements to provide:
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // typedef NodeType          - Type of Node in the graph
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // typedef ChildIteratorType - Type used to iterate over children in graph
32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // static NodeType *getEntryNode(const GraphType &)
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //    Return the entry node of the graph
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // static ChildIteratorType child_begin(NodeType *)
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // static ChildIteratorType child_end  (NodeType *)
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //    Return iterators that point to the beginning and ending of the child
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //    node list for the specified node.
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // typedef  ...iterator nodes_iterator;
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // static nodes_iterator nodes_begin(GraphType *G)
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // static nodes_iterator nodes_end  (GraphType *G)
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //    nodes_iterator/begin/end - Allow iteration over all nodes in the graph
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If anyone tries to use this class without having an appropriate
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // specialization, make an error.  If you get this error, it's because you
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // need to include the appropriate specialization of GraphTraits<> for your
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // graph, or you need to define it for a new graph type. Either that or
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // your argument to XXX_begin(...) is unknown or needs to have the proper .h
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // file #include'd.
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  //
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef typename GraphType::UnknownGraphTypeError NodeType;
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Inverse - This class is used as a little marker class to tell the graph
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// iterator to iterate over the graph in a graph defined "Inverse" ordering.
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Not all graphs define an inverse ordering, and if they do, it depends on
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// the graph exactly what that is.  Here's an example of usage with the
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// df_iterator:
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// for (; I != E; ++I) { ... }
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Which is equivalent to:
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// for (; I != E; ++I) { ... }
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate <class GraphType>
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct Inverse {
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const GraphType &Graph;
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  inline Inverse(const GraphType &G) : Graph(G) {}
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Provide a partial specialization of GraphTraits so that the inverse of an
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// inverse falls back to the original graph.
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumantemplate<class T>
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstruct GraphTraits<Inverse<Inverse<T> > > {
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef typename GraphTraits<T>::NodeType NodeType;
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return GraphTraits<T>::getEntryNode(G->Graph.Graph);
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static ChildIteratorType child_begin(NodeType* N) {
93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return GraphTraits<T>::child_begin(N);
94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  static ChildIteratorType child_end(NodeType* N) {
97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return GraphTraits<T>::child_end(N);
98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  }
99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman};
100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // End llvm namespace
102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif
104