3#include <boost/container/flat_map.hpp>
4#include <boost/range/adaptor/transformed.hpp>
5#include <boost/range/iterator_range.hpp>
34template <
class Vertex,
class EdgeData = detail::NoEdgeData>
37 using Links = boost::container::flat_map<Vertex, EdgeData>;
38 using Graph = boost::container::flat_map<Vertex, Links>;
54 connect(Vertex source, Vertex target, EdgeData e)
56 return graph_[source].emplace(target, e).second;
69 return connect(source, target, EdgeData{});
83 auto it =
graph_.find(source);
86 return it->second.erase(target) > 0;
99 edge(Vertex source, Vertex target)
const
101 auto it =
graph_.find(source);
104 auto edgeIt = it->second.find(target);
105 if (edgeIt != it->second.end())
106 return edgeIt->second;
131 return boost::adaptors::transform(
132 graph_, [](
typename Graph::value_type
const& v) {
return v.first; });
143 auto transform = [](
typename Links::value_type
const& link) {
return link.first; };
144 auto it =
graph_.find(source);
146 return boost::adaptors::transform(it->second, transform);
148 return boost::adaptors::transform(
empty, transform);
169 auto transform = [source](
typename Links::value_type
const& link) {
170 return Edge{source, link.first, link.second};
173 auto it =
graph_.find(source);
175 return boost::adaptors::transform(it->second, transform);
177 return boost::adaptors::transform(
empty, transform);
188 auto it =
graph_.find(source);
190 return it->second.size();
202 template <
class VertexName>
206 out <<
"digraph {\n";
207 for (
auto const& [vertex, links] :
graph_)
209 auto const fromName = vertexName(vertex);
210 for (
auto const& eData : links)
212 auto const toName = vertexName(eData.first);
213 out << fromName <<
" -> " << toName <<
";\n";
219 template <
class VertexName>
std::size_t outDegree(Vertex source) const
Vertex out-degree.
void saveDot(std::string const &fileName, VertexName &&vertexName) const
auto outEdges(Vertex source) const
Range of out edges.
bool connected(Vertex source, Vertex target) const
Check if two vertices are connected.
bool connect(Vertex source, Vertex target, EdgeData e)
Connect two vertices.
auto outVertices(Vertex source) const
Range over target vertices.
boost::container::flat_map< Vertex, EdgeData > Links
bool disconnect(Vertex source, Vertex target)
Disconnect two vertices.
void saveDot(std::ostream &out, VertexName &&vertexName) const
Save GraphViz dot file.
std::optional< EdgeData > edge(Vertex source, Vertex target) const
Return edge data between two vertices.
auto outVertices() const
Range over vertices in the graph.
boost::container::flat_map< Vertex, Links > Graph
bool connect(Vertex source, Vertex target)
Connect two vertices using default constructed edge data.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Vertices and data associated with an Edge.