LRDE Tiger Compiler  1.34a $Id: 7fef12e1f5fa43449d667a0eec1d837c40fc1202 $
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
graph.hxx
Go to the documentation of this file.
1 
6 #ifndef MISC_GRAPH_HXX
7 # define MISC_GRAPH_HXX
8 
9 # include <fstream>
10 # include <sstream>
11 
12 # include <algorithm>
13 
14 # include <misc/contract.hh>
15 # include <misc/algorithm.hh>
16 # include <misc/deref.hh>
17 
18 
19 namespace misc
20 {
21 
22  /*--------.
23  | Graph. |
24  `--------*/
25 
26  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
28  {
29  }
30 
31  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
34  vertex_add(const VertexLabel& l)
35  {
36  return boost::add_vertex(l, *this);
37  }
38 
39  /*-----------------------------------------------------------------.
40  | graph::print. |
41  | |
42  | For oriented graph, keeping edges bound to the source node looks |
43  | nicer, while an edge oriented dump is more appropriate for |
44  | unoriented graphs. In the latter case, be sure not to output |
45  | each edge twice. |
46  | |
47  | FIXME: We do lack something similar to Escape when "deref"ing, |
48  | for if there are strings in there, they should be escaped for |
49  | dotty. |
50  | |
51  | FIXME: Enforce the order by sorting before outputting. |
52  `-----------------------------------------------------------------*/
53 
54  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
55  std::ostream&
57  print(std::ostream& ostr) const
58  {
59  using misc::deref;
60 
61  std::string graphtype = boost::is_undirected(*this) ? "graph" : "digraph";
62  std::string link = boost::is_undirected(*this) ? "--" : "->";
63  ostr << "/* Graph Visualization */" << std::endl;
64 
65  ostr << graphtype << " \"" << name_get() << "\" {" << std::endl
66  << " node [shape=box];" << std::endl;
67 
69  vertex_iter_type vi_end;
70  for (tie(vi, vi_end) = boost::vertices(*this); vi != vi_end; ++vi)
71  {
72  ostr << " \"" << *vi << "\" "
73  << "[label=\"";
74  vertex_print(*vi, ostr);
75  ostr << "\"]" << std::endl;
76  }
77 
78  edge_iter_type ei;
79  edge_iter_type ei_end;
80  for (tie(ei, ei_end) = boost::edges(*this); ei != ei_end; ++ei)
81  {
82  std::ostringstream label;
83  label << deref <<(*this)[*ei];
84  ostr << " \"" << boost::source(*ei, *this) << "\" "
85  << link
86  << " \"" << boost::target(*ei, *this) << "\"";
87  if (label.str() != "")
88  ostr << " [label=\"" << label.str() << "\"]";
89  ostr << std::endl;
90  }
91 
92  epilogue_print(ostr);
93 
94  return ostr << "}" << std::endl;
95  }
96 
97  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
98  std::ostream&
100  epilogue_print(std::ostream& ostr) const
101  {
102  return ostr;
103  }
104 
105  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
106  void
108  print(std::string file) const
109  {
110  std::ofstream ofs;
111 
112  static unsigned cpt = 0;
113  if (file.empty())
114  {
115  std::stringstream sstr;
116  sstr << "graph-" << cpt++ << ".gv";
117  file = sstr.str();
118  }
119 
120  file += ".gv";
121  ofs.open(file.c_str());
122  print(ofs);
123  ofs.close();
124  }
125 
126  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
127  const std::string&
129  {
130  // For some reason, the following cast is needed with Boost 1.45.
131  return boost::get_property(static_cast<const super_type&>(*this),
132  boost::graph_name);
133  }
134 
135  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
136  void
138  name_set(const std::string& name)
139  {
140  boost::set_property(*this, boost::graph_name, name);
141  }
142 
143  template <typename Orientation, typename VertexLabel, typename EdgeLabel>
144  inline std::ostream&
145  operator<<(std::ostream& ostr,
147  {
148  return g.print(ostr);
149  }
150 
151  inline std::ostream& operator<<(std::ostream& ostr, empty)
152  {
153  return ostr;
154  }
155 
156 
157  /*----------------.
158  | DirectedGraph. |
159  `----------------*/
160 
161  template <typename VertexLabel, typename EdgeLabel>
163  {
164  }
165 
166  template <typename VertexLabel, typename EdgeLabel>
167  void
170  {
171  boost::add_edge(v1, v2, *this);
172  }
173 
174  // FIXME: Some code was deleted here (This needs to be done at TC-8).
175 
176  template <typename NodeLabel, typename EdgeLabel>
177  std::list<typename directed_graph<NodeLabel, EdgeLabel>::vertex_descriptor>
179  {
180  std::list<vertex_descriptor> res;
182  // FIXME: Some code was deleted here (This needs to be done at TC-8).
183  return res;
184  }
185 
186 
187  /*------------------.
188  | UndirectedGraph. |
189  `------------------*/
190 
191  template <typename VertexLabel, typename EdgeLabel>
193  {
194  }
195 
196  template <typename VertexLabel, typename EdgeLabel>
197  void
200  {
201  if (v1 > v2)
202  boost::add_edge(v2, v1, *this);
203  else
204  boost::add_edge(v1, v2, *this);
205  }
206 
207 } // namespace misc
208 
209 #endif // !MISC_GRAPH_HXX