Boost logo

Boost :

Subject: Re: [boost] [Variant] [BGL] Variant<edge_descriptor, edge_descriptor> is not EqualityComparable
From: Cosimo Calabrese (cosimo.calabrese_at_[hidden])
Date: 2009-11-12 09:00:09


Cosimo Calabrese wrote:
> Cosimo Calabrese wrote:
>> Andrew Sutton wrote:
>>>> // EqualityComparable concept, requested by IncidenceGraph concept
>>>> template <typename Graph1, typename Graph2>
>>>> inline bool operator!=(
>>>> const typename boost::graph_traits<
>>>> boost::union_graph<Graph1, Graph2>
>>>> >::edge_descriptor& left,
>>>> const typename boost::graph_traits<
>>>> boost::union_graph<Graph1, Graph2>
>>>> >::edge_descriptor& right )
>>>> {
>>>> return !( left == right );
>>>> }
>>>>
>>>>
>>>> UG ug( g1, g2 );
>>>>
>>>> graph_traits<UG>::edge_descriptor e1;
>>>> graph_traits<UG>::edge_descriptor e2;
>>>>
>>>> tie( e1, existence ) = edge( v1, v2, g );
>>>> tie( e2, existence ) = edge( v1, v2, g );
>>>>
>>>> e1 != e2;
>>>> }
>>>>
>>>
>>> I looks like the inequality operator is provided in terms of edge
>>> descriptors, but you're actually comparing variants. You may be able
>>> to get
>>> away with writing something like:
>>>
>>> template <typename G1, typename G2>
>>> bool operator!=(
>>> typename graph_traits<union_graph<G1, G2>>::edge_descriptor left,
>>> typename graph_traits<union_graph<G1, G2>>::edge_descriptor right)
>>> { ... }
>>>
>>> That should generate an inequality operator over variants, but
>>> prevent the
>>> template from becoming overly general, since its explicitly
>>> "specialized"
>>> for your union_graph.
>>>
>>> Maybe?
>>>
>>> Andrew Sutton
>>
>> I'm in agreement with you, but that code doesn't work. I don't know
>> why, I've tried it yesterday. This is my version. I've written it in
>> the global namespace, not in boost namespace:
>>
>> template <typename G1, typename G2>
>> bool operator!=( typename boost::graph_traits<boost::union_graph<G1,
>> G2> >::edge_descriptor left,
>> typename boost::graph_traits<boost::union_graph<G1,
>> G2> >::edge_descriptor right )
>> {
>> return !( left == right );
>> }
>>
>> Instead it works the follow, more general:
>>
>> template <typename T0_, typename T1>
>> inline bool operator!=( const boost::variant<T0_, T1>& left,
>> const boost::variant<T0_, T1>& right )
>> {
>> return !( left == right );
>> }
>>
>> I've written it in the same position of the first version, but it
>> provides the operator!=() for all the variant specialization...
>>
>> What do you think about?
>>
>
> I've tried to make esplicit the edge_descriptor definition, without
> using graph_traits class:
>
> template <typename G1, typename G2>
> bool operator!=(
> boost::variant<
> boost::WR1<typename boost::graph_traits<G1>::edge_descriptor>,
> boost::WR2<typename boost::graph_traits<G2>::edge_descriptor> >& left,
> boost::variant<
> boost::WR1<typename boost::graph_traits<G1>::edge_descriptor>,
> boost::WR2<typename boost::graph_traits<G2>::edge_descriptor> >& right )
> {
> return !( left == right );
> }
>
> but doesn't work, the compile doesn't resolve it.
>
> But this works:
>
> template <typename T1, typename T2>
> bool operator!=( boost::variant<boost::WR1<T1>, boost::WR2<T2> >& left,
> boost::variant<boost::WR1<T1>, boost::WR2<T2> >& right )
> {
> return !( left == right );
> }
>
> It is less general that the template <typename T0_, typename T1>
> version, but it involves the vertex_description too.
>
> It's make me crazy...
>
> Thanks,
> Cosimo Calabrese.
>
>

I've tried to write an output stream operator for vertex_descriptor, but
it happens the same thing.

This doesn't works:

namespace std
{
  template <typename Graph1, typename Graph2>
  std::ostream& operator<<(std::ostream& os,
  const typename boost::graph_traits<boost::union_graph<Graph1, Graph2>
>::vertex_descriptor& v)
  {
   if ( boost::get<WR1<graph_traits<Graph1>::vertex_descriptor> >( &v ) )
    os <<
      boost::get<WR1<graph_traits<Graph1>::vertex_descriptor>
>(v)._data;
   else
    os <<
      boost::get<WR2<graph_traits<Graph2>::vertex_descriptor> >(v)._data;
   return os;
  }
}

but this works:

namespace std
{
  template <typename T1, typename T2>
  std::ostream& operator<<(std::ostream& os,
                const boost::variant<boost::WR1<T1>, boost::WR2<T2> >& v)
  {
   if ( boost::get<boost::WR1<T1> >( &v ) )
    os << boost::get<WR1<T1> >( v )._data;
   else
    os << boost::get<WR2<T2> >( v )._data;
   return os;
  }
}

It seems the same case.

Cosimo Calabrese.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk