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