rippled
Loading...
Searching...
No Matches
Digraph.h
1#pragma once
2
3#include <boost/container/flat_map.hpp>
4#include <boost/range/adaptor/transformed.hpp>
5#include <boost/range/iterator_range.hpp>
6
7#include <fstream>
8#include <optional>
9#include <type_traits>
10#include <unordered_map>
11
12namespace xrpl {
13namespace detail {
14// Dummy class when no edge data needed for graph
16{
17};
18
19} // namespace detail
20
21namespace test {
22namespace csf {
23
34template <class Vertex, class EdgeData = detail::NoEdgeData>
36{
37 using Links = boost::container::flat_map<Vertex, EdgeData>;
38 using Graph = boost::container::flat_map<Vertex, Links>;
40
41 // Allows returning empty iterables for unknown vertices
43
44public:
53 bool
54 connect(Vertex source, Vertex target, EdgeData e)
55 {
56 return graph_[source].emplace(target, e).second;
57 }
58
66 bool
67 connect(Vertex source, Vertex target)
68 {
69 return connect(source, target, EdgeData{});
70 }
71
80 bool
81 disconnect(Vertex source, Vertex target)
82 {
83 auto it = graph_.find(source);
84 if (it != graph_.end())
85 {
86 return it->second.erase(target) > 0;
87 }
88 return false;
89 }
90
99 edge(Vertex source, Vertex target) const
100 {
101 auto it = graph_.find(source);
102 if (it != graph_.end())
103 {
104 auto edgeIt = it->second.find(target);
105 if (edgeIt != it->second.end())
106 return edgeIt->second;
107 }
108 return std::nullopt;
109 }
110
117 bool
118 connected(Vertex source, Vertex target) const
119 {
120 return edge(source, target) != std::nullopt;
121 }
122
128 auto
130 {
131 return boost::adaptors::transform(
132 graph_, [](typename Graph::value_type const& v) { return v.first; });
133 }
134
140 auto
141 outVertices(Vertex source) const
142 {
143 auto transform = [](typename Links::value_type const& link) { return link.first; };
144 auto it = graph_.find(source);
145 if (it != graph_.end())
146 return boost::adaptors::transform(it->second, transform);
147
148 return boost::adaptors::transform(empty, transform);
149 }
150
153 struct Edge
154 {
155 Vertex source;
156 Vertex target;
157 EdgeData data;
158 };
159
166 auto
167 outEdges(Vertex source) const
168 {
169 auto transform = [source](typename Links::value_type const& link) {
170 return Edge{source, link.first, link.second};
171 };
172
173 auto it = graph_.find(source);
174 if (it != graph_.end())
175 return boost::adaptors::transform(it->second, transform);
176
177 return boost::adaptors::transform(empty, transform);
178 }
179
186 outDegree(Vertex source) const
187 {
188 auto it = graph_.find(source);
189 if (it != graph_.end())
190 return it->second.size();
191 return 0;
192 }
193
202 template <class VertexName>
203 void
204 saveDot(std::ostream& out, VertexName&& vertexName) const
205 {
206 out << "digraph {\n";
207 for (auto const& [vertex, links] : graph_)
208 {
209 auto const fromName = vertexName(vertex);
210 for (auto const& eData : links)
211 {
212 auto const toName = vertexName(eData.first);
213 out << fromName << " -> " << toName << ";\n";
214 }
215 }
216 out << "}\n";
217 }
218
219 template <class VertexName>
220 void
221 saveDot(std::string const& fileName, VertexName&& vertexName) const
222 {
223 std::ofstream out(fileName);
225 }
226};
227
228} // namespace csf
229} // namespace test
230} // namespace xrpl
Directed graph.
Definition Digraph.h:36
std::size_t outDegree(Vertex source) const
Vertex out-degree.
Definition Digraph.h:186
void saveDot(std::string const &fileName, VertexName &&vertexName) const
Definition Digraph.h:221
auto outEdges(Vertex source) const
Range of out edges.
Definition Digraph.h:167
bool connected(Vertex source, Vertex target) const
Check if two vertices are connected.
Definition Digraph.h:118
bool connect(Vertex source, Vertex target, EdgeData e)
Connect two vertices.
Definition Digraph.h:54
auto outVertices(Vertex source) const
Range over target vertices.
Definition Digraph.h:141
boost::container::flat_map< Vertex, EdgeData > Links
Definition Digraph.h:37
bool disconnect(Vertex source, Vertex target)
Disconnect two vertices.
Definition Digraph.h:81
void saveDot(std::ostream &out, VertexName &&vertexName) const
Save GraphViz dot file.
Definition Digraph.h:204
std::optional< EdgeData > edge(Vertex source, Vertex target) const
Return edge data between two vertices.
Definition Digraph.h:99
auto outVertices() const
Range over vertices in the graph.
Definition Digraph.h:129
boost::container::flat_map< Vertex, Links > Graph
Definition Digraph.h:38
bool connect(Vertex source, Vertex target)
Connect two vertices using default constructed edge data.
Definition Digraph.h:67
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Vertices and data associated with an Edge.
Definition Digraph.h:154