Boost logo

Boost Users :

Subject: Re: [Boost-users] [GIL] does gil::variant<mpl::vector3<A, B, C> > constructor accept instances of gil::variant<mpl::vector2<A, B> > ?
From: Nicolas Lelong (rotoglup_at_[hidden])
Date: 2010-05-12 05:59:20


Lubomir,

> It was not possible to assign and copy construct between two gil::variants
containing different subsets of types.
> I just submitted and update that makes this possible so you should sync to
trunk.

thanks for your quick reaction !

I am all for code reuse where it makes sense. In this case gil::variant is
> very small and we are not duplicating much code. If someone feels strongly
> about using boost::variant instead and is willing to take a stab at redoing
> the experiments, and they show acceptable performance (things may have
> changed over the past 5 years), I would be ok with switching to
> boost::variant.
>

I'm no template metaprogramming guru, but I tried a quick experiment on my
code base. Don't know if its a valid approach.

My current image library uses gil, any_image_view, and some binary functions
among them, it currently builds in about 33 seconds, using MSVC8 SP1.

I made a quick and dirty test, simply tried to change gil variant.hpp to use
boost::variant, this lead to something like that (incomplete exemple, I did
not look to be exhaustive) for class boost::gil::variant :

template <typename Types> // models MPL Random Access Container
class variant : public boost::make_variant_over<Types>::type {
public:

  typedef typename boost::make_variant_over<Types>::type parent_t;

  variant() : parent_t() {}
  template <typename T> explicit variant(const T& obj) : parent_t(obj) {}
  variant(const variant& obj) : parent_t((const parent_t&)obj) {}

  template <typename T> variant& operator=(const T& obj) {
parent_t::operator=(obj); return *this; }
  variant& operator=(const variant& obj) { parent_t::operator=((const
parent_t&)obj); return *this; }

  template <typename T> const T& _dynamic_cast() const { return get<const
T&>(*this); }
  template <typename T> T& _dynamic_cast() { return
get<T&>(*this); }
};

I also changed apply_operation.hpp to use boost::variant :

/// \ingroup Variant
/// \brief Invokes a generic mutable operation (represented as a unary
function object) on a variant
template <typename Types, typename UnaryOp> GIL_FORCEINLINE
typename UnaryOp::result_type apply_operation(boost::variant<Types>& arg,
UnaryOp op) {
    return apply_visitor(op, arg);
}

/// \ingroup Variant
/// \brief Invokes a generic constant operation (represented as a unary
function object) on a variant
template <typename Types, typename UnaryOp> GIL_FORCEINLINE
typename UnaryOp::result_type apply_operation(const boost::variant<Types>&
arg, UnaryOp op) {
    return apply_visitor(op, arg);
}

/// \ingroup Variant
/// \brief Invokes a generic constant operation (represented as a binary
function object) on two variants
template <typename Types1, typename Types2, typename BinaryOp>
GIL_FORCEINLINE
typename BinaryOp::result_type apply_operation(const boost::variant<Types1>&
arg1, const boost::variant<Types2>& arg2, BinaryOp op) {
    return apply_visitor(op, arg1, arg2);
}

I was able to compile most of my imaging lib this way, I had some compile
error I could not solve, related to ambiguous conversions, so I removed some
of my lib code.
The compile time went up to 52 seconds, almost 57% more. Of course, this may
be a bad test, as I added an indirection layer, but I did not want to break
my code related to 'boost::gil::apply_operation'.

> Note that gil::variant is not typically used directly. It is a base class
> for gil::any_image and gil::any_image_view. You would need to deal with
> gil::variant only if you are a pretty advanced GIL user.
>

True, but it's nevertheless confusing to use both variant types in the same
code base ; they don't have the same interface - perhaps boost::gil::variant
could have a subset of boost::variant interface ? for instance, an 'empty()'
method would be convenient for boost::gil::variant.

Cheers,
Nicolas



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net