@@ -19,8 +19,7 @@ namespace reactor {
1919template <class E , class P > class Graph {
2020private:
2121 std::map<E, std::vector<std::pair<P, E>>> graph_;
22- std::size_t index{0 };
23- std::map<E, std::string> name_map{};
22+ std::set<E> nodes_{};
2423
2524 // custom compare operator this is required if u want special key values in std::map
2625 // this is required for the Graph::get_edges() method
@@ -54,6 +53,8 @@ public:
5453
5554 // adds a single edge to the graph structure
5655 void add_edge (E source, E destination, P properties) noexcept {
56+ nodes_.insert (source);
57+ nodes_.insert (destination);
5758 if (graph_.find (source) == std::end (graph_)) {
5859 Path edges{std::make_pair (properties, destination)};
5960 graph_[source] = edges;
@@ -62,6 +63,8 @@ public:
6263 }
6364 }
6465
66+ auto get_nodes () -> std::set<E> { return nodes_; }
67+
6568 // this groups connections by same source and properties
6669 [[nodiscard]] auto get_edges () const noexcept -> std::map<map_key, std::vector<E>, map_key_compare> {
6770 std::map<map_key, std::vector<E>, map_key_compare> all_edges{};
@@ -89,39 +92,16 @@ public:
8992 return keys;
9093 }
9194
92- auto name_resolver (E object) -> std::string {
93- char names[] = " ABCDEFGHIJKLMNOPQRSTUVGXYZabcdefghijklmnopqrstuvgxyz" ;
94- if (name_map.find (object) == std::end (name_map)) {
95- name_map[object] = names[index];
96- index++;
97- return std::string{names[index - 1 ], 1 };
98- }
99- return name_map[object];
100- }
101-
10295 // the return type looks a little bit cursed what is happening here ?
10396 // we have a map from the destination as a key to a list of paths through the graph.
10497 // A path here is modelled by a list of edges (with properties and the next vertex).
10598 auto naive_spanning_tree (E source) noexcept -> std::vector<std::vector<std::pair<P, E>>> {
106- auto result = recursive_spanning_tree (source, std::vector<E>{});
107-
108- std::string mermaid_string = " graph TD;\n " ;
109-
110- for (auto path : result ) {
111- mermaid_string += std::string (" " ) + name_resolver (source);
112- for (auto edge : path) {
113- mermaid_string += std::string (" -->" )+ name_resolver (edge.second );
114- }
115- mermaid_string += std::string (" ;\n " );
116-
117- }
118- // std::cout << "EDGE: \n" << mermaid_string << std::endl;
119- return result;
99+ return recursive_spanning_tree (source, std::vector<E>{});
120100 }
121101
122-
123102 // this function goes recursively though the graph and tries to find every possible path
124- auto recursive_spanning_tree (E source_node, std::vector<E> visited_nodes) -> std::vector<std::vector<std::pair<P, E>>> {
103+ auto recursive_spanning_tree (E source_node, std::vector<E> visited_nodes)
104+ -> std::vector<std::vector<std::pair<P, E>>> {
125105 std::vector<Path> paths{};
126106
127107 if (graph_[source_node].empty ()) {
@@ -138,7 +118,7 @@ public:
138118 auto temp_nodes = visited_nodes;
139119 temp_nodes.push_back (current_node);
140120
141- for (auto path: recursive_spanning_tree (current_node, temp_nodes)) {
121+ for (auto path : recursive_spanning_tree (current_node, temp_nodes)) {
142122 path.insert (std::begin (path), child);
143123 paths.push_back (path);
144124 }
@@ -154,9 +134,8 @@ public:
154134 auto spanning_tre = naive_spanning_tree (source);
155135 std::vector<Path> relevant_paths{};
156136
157- std::copy_if (spanning_tre.begin (), spanning_tre.end (), std::back_inserter (relevant_paths), [destination](Path path) {
158- return (*path.end ()).second == destination;
159- });
137+ std::copy_if (spanning_tre.begin (), spanning_tre.end (), std::back_inserter (relevant_paths),
138+ [&, destination](Path path) { return path[path.size () - 1 ].second == destination; });
160139
161140 if (relevant_paths.empty ()) {
162141 return std::nullopt ;
@@ -185,12 +164,25 @@ public:
185164 }
186165 }
187166
188- auto to_mermaid () noexcept -> std::string {
167+ auto to_mermaid () const noexcept -> std::string {
168+ std::size_t index{0 };
169+ std::map<E, std::string> name_map{};
189170 std::string mermaid_string = " graph TD;\n " ;
190171
172+ auto name_resolver = [&](E object) -> std::string {
173+ char names[] = " ABCDEFGHIJKLMNOPQRSTUVGXYZabcdefghijklmnopqrstuvgxyz" ;
174+ if (name_map.find (object) == std::end (name_map)) {
175+ name_map[object] = names[index];
176+ index++;
177+ return std::string{names[index - 1 ], 1 };
178+ }
179+ return name_map[object];
180+ };
181+
191182 for (const auto & [source, destinations] : graph_) {
192183 for (auto dest : destinations) {
193- mermaid_string += std::string (" " ) + name_resolver (source) + std::string (" -->" ) + name_resolver (dest.second ) + std::string (" ;\n " );
184+ mermaid_string += std::string (" " ) + name_resolver (source) + std::string (" -->" ) +
185+ name_resolver (dest.second ) + std::string (" ;\n " );
194186 }
195187 }
196188 return mermaid_string;
0 commit comments