From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- tiger-compiler/lib/misc/graph.hxx | 171 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 tiger-compiler/lib/misc/graph.hxx (limited to 'tiger-compiler/lib/misc/graph.hxx') diff --git a/tiger-compiler/lib/misc/graph.hxx b/tiger-compiler/lib/misc/graph.hxx new file mode 100644 index 0000000..fe97cf7 --- /dev/null +++ b/tiger-compiler/lib/misc/graph.hxx @@ -0,0 +1,171 @@ +/** + ** \file misc/graph.hxx + ** \brief Undirected/oriented graph implementation. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include + +namespace misc +{ + /*--------. + | Graph. | + `--------*/ + + template + typename graph::vertex_descriptor + graph::vertex_add(const VertexLabel& l) + { + return boost::add_vertex(l, *this); + } + + /*-----------------------------------------------------------------. + | graph::print. | + | | + | For oriented graph, keeping edges bound to the source node looks | + | nicer, while an edge oriented dump is more appropriate for | + | unoriented graphs. In the latter case, be sure not to output | + | each edge twice. | + | | + | FIXME: We do lack something similar to Escape when "deref"ing, | + | for if there are strings in there, they should be escaped for | + | dotty. | + | | + | FIXME: Enforce the order by sorting before outputting. | + `-----------------------------------------------------------------*/ + + template + std::ostream& + graph::print(std::ostream& ostr) const + { + using misc::deref; + + std::string graphtype = boost::is_undirected(*this) ? "graph" : "digraph"; + std::string link = boost::is_undirected(*this) ? "--" : "->"; + ostr << "/* Graph Visualization */\n"; + + ostr << graphtype << " \"" << name_get() << "\" {\n" + << " node [shape=box];\n"; + + for (auto [vi, vi_end] = boost::vertices(*this); vi != vi_end; ++vi) + { + ostr << " \"" << *vi << "\" " + << "[label=\""; + vertex_print(*vi, ostr); + ostr << "\"]\n"; + } + + for (auto [ei, ei_end] = boost::edges(*this); ei != ei_end; ++ei) + { + std::ostringstream label; + label << deref << (*this)[*ei]; + ostr << " \"" << boost::source(*ei, *this) << "\" " << link << " \"" + << boost::target(*ei, *this) << "\""; + if (label.str() != "") + ostr << " [label=\"" << label.str() << "\"]"; + ostr << '\n'; + } + + epilogue_print(ostr); + + return ostr << "}\n"; + } + + template + std::ostream& graph::epilogue_print( + std::ostream& ostr) const + { + return ostr; + } + + template + void graph::print(std::string file) const + { + std::ofstream ofs; + + static unsigned cpt = 0; + if (file.empty()) + { + std::stringstream sstr; + sstr << "graph-" << cpt << ".gv"; + ++cpt; + file = sstr.str(); + } + + file += ".gv"; + ofs.open(file.c_str()); + print(ofs); + ofs.close(); + } + + template + const std::string& + graph::name_get() const + { + // For some reason, the following cast is needed with Boost 1.45. + return boost::get_property(static_cast(*this), + boost::graph_name); + } + + template + void + graph::name_set(const std::string& name) + { + boost::set_property(*this, boost::graph_name, name); + } + + template + inline std::ostream& + operator<<(std::ostream& ostr, + const graph& g) + { + return g.print(ostr); + } + + inline std::ostream& operator<<(std::ostream& ostr, empty) { return ostr; } + + /*----------------. + | DirectedGraph. | + `----------------*/ + + template + void + directed_graph::edge_add(const vertex_descriptor& v1, + const vertex_descriptor& v2) + { + boost::add_edge(v1, v2, *this); + } + + template + std::vector::vertex_descriptor> + directed_graph::topological_sort() const + { + std::vector res; + misc::set visited; + return res; + } + + /*------------------. + | UndirectedGraph. | + `------------------*/ + + template + void undirected_graph::edge_add( + const vertex_descriptor& v1, + const vertex_descriptor& v2) + { + if (v1 > v2) + boost::add_edge(v2, v1, *this); + else + boost::add_edge(v1, v2, *this); + } + +} // namespace misc -- cgit v1.2.3