I am trying to figure out how to use boost::graph to store some information. However, there is information I want tied to each vertex. Staring at the documentation for the l
I don't like the nested-template property approach of boost::graph, so I wrote a small wrapper around everything, that basically allows to put any struct/class as a vertex/edge property. One can access properties accessing the struct members.
To keep it flexible these structs are defined as template parameter.
Here the Code:
/* definition of basic boost::graph properties */
enum vertex_properties_t { vertex_properties };
enum edge_properties_t { edge_properties };
namespace boost {
BOOST_INSTALL_PROPERTY(vertex, properties);
BOOST_INSTALL_PROPERTY(edge, properties);
}
/* the graph base class template */
template < typename VERTEXPROPERTIES, typename EDGEPROPERTIES >
class Graph
{
public:
/* an adjacency_list like we need it */
typedef adjacency_list<
setS, // disallow parallel edges
listS, // vertex container
bidirectionalS, // directed graph
property,
property
> GraphContainer;
/* a bunch of graph-specific typedefs */
typedef typename graph_traits::vertex_descriptor Vertex;
typedef typename graph_traits::edge_descriptor Edge;
typedef std::pair EdgePair;
typedef typename graph_traits::vertex_iterator vertex_iter;
typedef typename graph_traits::edge_iterator edge_iter;
typedef typename graph_traits::adjacency_iterator adjacency_iter;
typedef typename graph_traits::out_edge_iterator out_edge_iter;
typedef typename graph_traits::degree_size_type degree_t;
typedef std::pair adjacency_vertex_range_t;
typedef std::pair out_edge_range_t;
typedef std::pair vertex_range_t;
typedef std::pair edge_range_t;
/* constructors etc. */
Graph()
{}
Graph(const Graph& g) :
graph(g.graph)
{}
virtual ~Graph()
{}
/* structure modification methods */
void Clear()
{
graph.clear();
}
Vertex AddVertex(const VERTEXPROPERTIES& prop)
{
Vertex v = add_vertex(graph);
properties(v) = prop;
return v;
}
void RemoveVertex(const Vertex& v)
{
clear_vertex(v, graph);
remove_vertex(v, graph);
}
EdgePair AddEdge(const Vertex& v1, const Vertex& v2, const EDGEPROPERTIES& prop_12, const EDGEPROPERTIES& prop_21)
{
/* TODO: maybe one wants to check if this edge could be inserted */
Edge addedEdge1 = add_edge(v1, v2, graph).first;
Edge addedEdge2 = add_edge(v2, v1, graph).first;
properties(addedEdge1) = prop_12;
properties(addedEdge2) = prop_21;
return EdgePair(addedEdge1, addedEdge2);
}
/* property access */
VERTEXPROPERTIES& properties(const Vertex& v)
{
typename property_map::type param = get(vertex_properties, graph);
return param[v];
}
const VERTEXPROPERTIES& properties(const Vertex& v) const
{
typename property_map::const_type param = get(vertex_properties, graph);
return param[v];
}
EDGEPROPERTIES& properties(const Edge& v)
{
typename property_map::type param = get(edge_properties, graph);
return param[v];
}
const EDGEPROPERTIES& properties(const Edge& v) const
{
typename property_map::const_type param = get(edge_properties, graph);
return param[v];
}
/* selectors and properties */
const GraphContainer& getGraph() const
{
return graph;
}
vertex_range_t getVertices() const
{
return vertices(graph);
}
adjacency_vertex_range_t getAdjacentVertices(const Vertex& v) const
{
return adjacent_vertices(v, graph);
}
int getVertexCount() const
{
return num_vertices(graph);
}
int getVertexDegree(const Vertex& v) const
{
return out_degree(v, graph);
}
/* operators */
Graph& operator=(const Graph &rhs)
{
graph = rhs.graph;
return *this;
}
protected:
GraphContainer graph;
};
Using this you can access properties like this:
struct VertexProperties {
int i;
};
struct EdgeProperties {
};
typedef Graph MyGraph;
MyGraph g;
VertexProperties vp;
vp.i = 42;
MyGraph::Vertex v = g.AddVertex(vp);
g.properties(v).i = 23;
Of course you may have other needs for your graph's structure, but modification of the code above should be pretty easy.