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