
Boost : 
Subject: Re: [boost] [BGL] Multithread problem inserting edges and exploring the same graph
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 20091005 11:23:06
Jeremiah Willcock ha scritto:
> I think that should work. You might really want a tagged union type,
> though (boost::variant with some guarantee that the edge descriptor
> types of the two graphs are different is an example). You would need to
> do wrapping of each graph's descriptors in the union iterator then,
> though. That would remove the restrictions on edges that you gave above.
> I don't know what you need as far as properties; those might need to be
> combined as well.
>
Hi Jeremiah,
I've readed some days ago your suggestions about using boost::variant,
but I ignored what boost::variant is. So I've spent some time to study
it, and now I think I understand what you have suggested to me. E.g. the
edge_descriptor of union_graph adaptor is a boost::variant, that
contains the edge_descriptor of both the graph. When I call the source()
function I pass an edge_descriptor to it, but the source() doesn't know
if the edge_descriptor belongs to one or another graph. So the source()
function use a source_visitor, that distinguish between the
edge_descriptors, and call the source() on the right graph.
Can you take a look to the attached code? Is this that you meant? I've
writed only the case of the source() function, but at every concept
function corresponds a visitor.
Thanks for your help,
Cosimo Calabrese.
class union_graph;
//===========================================================================
// source_visitor
template<typename Graph1, typename Graph2>
class source_visitor : public boost::static_visitor<>
{
public:
source_visitor( const union_graph<Graph1, Graph2>& g ) : m_g( g ) {}
union_graph<Graph1, Graph2>::vertex_descriptor
operator()( const typename graph_traits<Graph1>::edge_descriptor& e ) const
{ return source( e, m_g.m_g1 ); }
union_graph<Graph1, Graph2>::vertex_descriptor
operator()( const typename graph_traits<Graph2>::edge_descriptor& e ) const
{ return source( e, m_g.m_g2 ); }
private:
const union_graph<Graph1, Graph2>& m_g;
};
//===========================================================================
// union_graph
template<typename Graph1, typename Graph2>
class union_graph
{
public:
union_graph( const Graph1& g1, const Graph2& g2 ) : m_g1( g1 ), m_g2( g2 ) {}
typedef graph_traits<Graph1> Traits1;
typedef graph_traits<Graph2> Traits2;
typedef typename boost::variant( Traits1::vertex_descriptor,
Traits2::vertex_descriptor ) vertex_descriptor;
typedef typename boost::variant( Traits1::edge_descriptor,
Traits2::edge_descriptor ) edge_descriptor;
// ...
friend class source_visitor;
private:
const Graph1& m_g1;
const Graph2& m_g2;
};
template<typename Graph1, typename Graph2>
typename union_graph<Graph1, Graph2>::vertex_descriptor
source( const typename union_graph<Graph1, Graph2>::edge_descriptor& e,
const union_graph<Graph1, Graph2>& g )
{
return boost::apply_visitor( source_visitor( g ), e );
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk