Browse Source

dot: directed/undirected support

Michele Caini 3 years ago
parent
commit
0eb5b0437b
4 changed files with 34 additions and 6 deletions
  1. 1 1
      src/entt/graph/adjacency_matrix.hpp
  2. 13 2
      src/entt/graph/dot.hpp
  3. 2 2
      src/entt/graph/fwd.hpp
  4. 18 1
      test/entt/graph/dot.cpp

+ 1 - 1
src/entt/graph/adjacency_matrix.hpp

@@ -161,7 +161,7 @@ template<typename Container>
 template<typename Category, typename Allocator>
 class adjacency_matrix {
     using alloc_traits = std::allocator_traits<Allocator>;
-    static_assert(std::is_base_of_v<undirected_tag, Category>, "Invalid graph category");
+    static_assert(std::is_base_of_v<directed_tag, Category>, "Invalid graph category");
     static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");
     using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
 

+ 13 - 2
src/entt/graph/dot.hpp

@@ -2,6 +2,7 @@
 #define ENTT_GRAPH_DOT_HPP
 
 #include <ostream>
+#include <type_traits>
 #include "adjacency_matrix.hpp"
 
 namespace entt {
@@ -16,7 +17,13 @@ namespace entt {
  */
 template<typename Graph, typename Writer>
 void dot(std::ostream &out, const Graph &graph, Writer writer) {
-    out << "digraph{";
+    static_assert(std::is_base_of_v<directed_tag, typename Graph::graph_category>, "Invalid graph category");
+
+    if constexpr(std::is_same_v<typename Graph::graph_category, undirected_tag>) {
+        out << "graph{";
+    } else {
+        out << "digraph{";
+    }
 
     for(auto &&vertex: graph.vertices()) {
         out << vertex << "[";
@@ -25,7 +32,11 @@ void dot(std::ostream &out, const Graph &graph, Writer writer) {
     }
 
     for(auto [lhs, rhs]: graph.edges()) {
-        out << lhs << "->" << rhs << ";";
+        if constexpr(std::is_same_v<typename Graph::graph_category, undirected_tag>) {
+            out << lhs << "--" << rhs << ";";
+        } else {
+            out << lhs << "->" << rhs << ";";
+        }
     }
 
     out << "}";

+ 2 - 2
src/entt/graph/fwd.hpp

@@ -8,10 +8,10 @@
 namespace entt {
 
 /*! @brief Undirected graph category tag. */
-struct undirected_tag {};
+struct directed_tag {};
 
 /*! @brief Directed graph category tag. */
-struct directed_tag: undirected_tag {};
+struct undirected_tag: directed_tag {};
 
 template<typename, typename = std::allocator<std::size_t>>
 class adjacency_matrix;

+ 18 - 1
test/entt/graph/dot.cpp

@@ -4,7 +4,7 @@
 #include <entt/graph/adjacency_matrix.hpp>
 #include <entt/graph/dot.hpp>
 
-TEST(Dot, DefaultWriter) {
+TEST(Dot, DirectedGraph) {
     std::ostringstream output{};
     entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
 
@@ -21,6 +21,23 @@ TEST(Dot, DefaultWriter) {
     ASSERT_EQ(str, expected);
 }
 
+TEST(Dot, UndirectedGraph) {
+    std::ostringstream output{};
+    entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
+
+    adjacency_matrix.insert(0u, 1u);
+    adjacency_matrix.insert(1u, 2u);
+    adjacency_matrix.insert(0u, 2u);
+
+    entt::dot(output, adjacency_matrix);
+
+    const std::string expected = "graph{0[];1[];2[];0--1;0--2;1--0;1--2;2--0;2--1;}";
+    const auto str = output.str();
+
+    ASSERT_FALSE(str.empty());
+    ASSERT_EQ(str, expected);
+}
+
 TEST(Dot, CustomWriter) {
     std::ostringstream output{};
     entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};