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.hh | 213 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 tiger-compiler/lib/misc/graph.hh (limited to 'tiger-compiler/lib/misc/graph.hh') diff --git a/tiger-compiler/lib/misc/graph.hh b/tiger-compiler/lib/misc/graph.hh new file mode 100644 index 0000000..c21aa99 --- /dev/null +++ b/tiger-compiler/lib/misc/graph.hh @@ -0,0 +1,213 @@ +/** + ** \file misc/graph.hh + ** \brief Undirected/oriented graph definition. + */ + +#pragma once + +#include +#include +#include +#include + +#include // Required by boost/graph/detail/edge.hpp. +/* Forward declarations to help the compiler not to mix up the + namespace `target' with `boost::target'. This happens in the + instantiation of graph concepts in boost/graph/graph_concepts.hpp + if this forward declaration is omitted. */ +#include + +namespace boost +{ + template + class adjacency_list; + + template + inline Vertex target(const detail::edge_base& e, + const adjacency_list&); + +} // namespace boost + +#include + +#include + +/// Handling of generic, oriented or undirected, graph. +namespace misc +{ + /*--------. + | Graph. | + `--------*/ + + /// Graph property: name. + using name_prop_type = boost::property; + + template + class graph + : public boost::adjacency_list + { + public: + virtual ~graph() = default; + + public: + using self_type = graph; + using super_type = boost::adjacency_list; + using vertex_descriptor = typename super_type::vertex_descriptor; + + /// Iterators. + public: + /// \{ + /// Iterator on the vertices of a graph. + using vertex_iter_type = + typename boost::graph_traits::vertex_iterator; + /// Iterator on the edges of a graph. + using edge_iter_type = + typename boost::graph_traits::edge_iterator; + /// \} + + /// Graph manipulation. + /// \{ + public: + /// \brief Add a vertex to the graph. + /// + /// Just a wrapper around boost::add_vertex. + vertex_descriptor vertex_add(const VertexLabel& l); + /// Add an edge between two vertices. + virtual void edge_add(const vertex_descriptor& v1, + const vertex_descriptor& v2) = 0; + /// \} + + /// Graph pretty printing. + /// \{ + public: + virtual std::ostream& print(std::ostream& ostr) const; + virtual std::ostream& epilogue_print(std::ostream& ostr) const; + virtual void print(std::string file) const; + + private: + /// Print the label of vertex of a graph. + virtual std::ostream& vertex_print(vertex_descriptor v, + std::ostream& ostr) const = 0; + /// \} + + /// Graph name. + /// \{ + public: + const std::string& name_get() const; + void name_set(const std::string& name); + /// \} + }; + + template + std::ostream& operator<<(std::ostream& ostr, + const graph& g); + + // An helper class when we do not want any data attached to vertex + // or an edge. + struct empty + {}; + inline std::ostream& operator<<(std::ostream& ostr, empty); + + /*----------------------------------------------------. + | Specialization for directed (bidirectional) graph. | + `----------------------------------------------------*/ + + /* Note that boost::bidirectionalS is like boost::directedS, except + that it provides access to both in-edges and out-edges, whereas + boost::directedS gives us only out-edges. The consequence is + that a bidirectional graph is twice as large as its directed + version. */ + template + class directed_graph + : public graph + { + public: + using self_type = directed_graph; + using super_type = graph; + using vertex_descriptor = typename super_type::vertex_descriptor; + + public: + /// Iterator on the vertices of a directed_graph. + using vertex_iter_type = + typename boost::graph_traits::vertex_iterator; + /// Iterator on the neighbors of the vertex of a directed_graph. + using neighb_iter_type = + typename boost::graph_traits::adjacency_iterator; + + /// Iterators. + /// \{ + public: + /// \brief Add an edge between two vertices. + /// + /// This is just a wrapper around boost::add_edge. + void edge_add(const vertex_descriptor& v1, + const vertex_descriptor& v2) override; + /// \} + + /// \brief Topological sort. + /// + /// This version (algorithm 17.5 in Modern Compiler Implementation + /// in ML, p. 390) is not the same as boost::topological_sort since + /// the former works on directed acyclic graphs (DAGs) and the latter + /// doesn't. + /// + /// \{ + public: + std::vector topological_sort() const; + /// \} + }; + + /*--------------------------------------. + | Specialization for undirected graph. | + `--------------------------------------*/ + + template + class undirected_graph + : public graph + { + public: + using super_type = graph; + using vertex_descriptor = typename super_type::vertex_descriptor; + + public: + /// \brief Add an edge between two vertices. + /// + /// Use this method instead of boost::add_edge directly to keep + /// the order between the ends of an edge. + void edge_add(const vertex_descriptor& v1, + const vertex_descriptor& v2) override; + }; + +} // namespace misc + +#include -- cgit v1.2.3