1#ifndef XRPL_TEST_CSF_DIGRAPH_H_INCLUDED 
    2#define XRPL_TEST_CSF_DIGRAPH_H_INCLUDED 
    4#include <boost/container/flat_map.hpp> 
    5#include <boost/range/adaptor/transformed.hpp> 
    6#include <boost/range/iterator_range.hpp> 
   35template <
class Vertex, 
class EdgeData = detail::NoEdgeData>
 
   38    using Links = boost::container::flat_map<Vertex, EdgeData>;
 
   39    using Graph = boost::container::flat_map<Vertex, Links>;
 
   55    connect(Vertex source, Vertex target, EdgeData e)
 
   57        return graph_[source].emplace(target, e).second;
 
 
   70        return connect(source, target, EdgeData{});
 
 
   84        auto it = 
graph_.find(source);
 
   87            return it->second.erase(target) > 0;
 
 
  100    edge(Vertex source, Vertex target)
 const 
  102        auto it = 
graph_.find(source);
 
  105            auto edgeIt = it->second.find(target);
 
  106            if (edgeIt != it->second.end())
 
  107                return edgeIt->second;
 
 
  132        return boost::adaptors::transform(
 
  134            [](
typename Graph::value_type 
const& v) { 
return v.first; });
 
 
  145        auto transform = [](
typename Links::value_type 
const& link) {
 
  148        auto it = 
graph_.find(source);
 
  150            return boost::adaptors::transform(it->second, transform);
 
  152        return boost::adaptors::transform(
empty, transform);
 
 
  173        auto transform = [source](
typename Links::value_type 
const& link) {
 
  174            return Edge{source, link.first, link.second};
 
  177        auto it = 
graph_.find(source);
 
  179            return boost::adaptors::transform(it->second, transform);
 
  181        return boost::adaptors::transform(
empty, transform);
 
 
  192        auto it = 
graph_.find(source);
 
  194            return it->second.size();
 
 
  206    template <
class VertexName>
 
  210        out << 
"digraph {\n";
 
  211        for (
auto const& [vertex, links] : 
graph_)
 
  213            auto const fromName = vertexName(vertex);
 
  214            for (
auto const& eData : links)
 
  216                auto const toName = vertexName(eData.first);
 
  217                out << fromName << 
" -> " << toName << 
";\n";
 
 
  223    template <
class VertexName>
 
 
bool connect(Vertex source, Vertex target)
Connect two vertices using default constructed edge data.
 
boost::container::flat_map< Vertex, EdgeData > Links
 
bool connected(Vertex source, Vertex target) const
Check if two vertices are connected.
 
boost::container::flat_map< Vertex, Links > Graph
 
auto outVertices() const
Range over vertices in the graph.
 
void saveDot(std::ostream &out, VertexName &&vertexName) const
Save GraphViz dot file.
 
auto outVertices(Vertex source) const
Range over target vertices.
 
auto outEdges(Vertex source) const
Range of out edges.
 
std::size_t outDegree(Vertex source) const
Vertex out-degree.
 
std::optional< EdgeData > edge(Vertex source, Vertex target) const
Return edge data between two vertices.
 
void saveDot(std::string const &fileName, VertexName &&vertexName) const
 
bool disconnect(Vertex source, Vertex target)
Disconnect two vertices.
 
bool connect(Vertex source, Vertex target, EdgeData e)
Connect two vertices.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Vertices and data associated with an Edge.