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(
graph_, [](
typename Graph::value_type
const& v) {
return v.first; });
142 auto transform = [](
typename Links::value_type
const& link) {
return link.first; };
143 auto it =
graph_.find(source);
145 return boost::adaptors::transform(it->second, transform);
147 return boost::adaptors::transform(
empty, transform);
168 auto transform = [source](
typename Links::value_type
const& link) {
169 return Edge{source, link.first, link.second};
172 auto it =
graph_.find(source);
174 return boost::adaptors::transform(it->second, transform);
176 return boost::adaptors::transform(
empty, transform);
187 auto it =
graph_.find(source);
189 return it->second.size();
201 template <
class VertexName>
205 out <<
"digraph {\n";
206 for (
auto const& [vertex, links] :
graph_)
208 auto const fromName = vertexName(vertex);
209 for (
auto const& eData : links)
211 auto const toName = vertexName(eData.first);
212 out << fromName <<
" -> " << toName <<
";\n";
218 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.