Boost logo

Boost :

Subject: Re: [boost] [BGL] Multithread problem inserting edges and exploring the same graph
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 2009-10-05 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