Template operator() overloading for types in a mpl::vector

View: New views
5 Messages — Rating Filter:   Alert me  

Template operator() overloading for types in a mpl::vector

by Olivier Tournaire :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I am currently trying to write a simple functor, and I would like to have the same overload for the operator () for all types in a mpl::vector.

// Types definitions

// Gray image types
typedef boost::mpl::vector< boost::gil::gray8_image_t , boost::gil::gray16_image_t , boost::gil::gray32_image_t, boost::gil::gray32F_image_t , boost::gil::gray64F_image_t > gray_image_types;
// RGB image types
typedef boost::mpl::vector< boost::gil::rgb8_image_t , boost::gil::rgb16_image_t , boost::gil::rgb32_image_t > rgb_image_types;


// Functor to compute min / max of an image over channels
struct pixel_compare_less
{
    template <typename PixelType>
    bool operator()( const PixelType& p1 , const PixelType& p2 ) const
    {
        return at_c<0>(p1) < at_c<0>(p2);
    }
};

struct any_view_min_max
{
    typedef std::pair<float, float> result_type;

    template <typename View>
    result_type operator()(const View& v) const
    {
        typedef typename View::iterator iterator;
        std::pair< iterator, iterator > result = boost::minmax_element( v.begin() , v.end() , pixel_compare_less() );
        return std::make_pair( *(result.first) , *(result.second) );
    }
};

This works fine for 'gray_image_types', but need to be specialized for types in rgb_image_types. The specialization is the same, so, I am looking for an automated way to do this. "Manually", I can write this:

template <>
any_view_min_max_optimized::result_type any_view_min_max_optimized::operator()<rgba8_view_t>(const rgb8_view_t& v) const
{
    // ...
}

template <>
any_view_min_max_optimized::result_type any_view_min_max_optimized::operator()<rgba16_view_t>(const rgb16_view_t& v) const
{
    // ...
}

And so on ... Could you help me to have an efficient way to do this for all types 'rgb_image_types' without writing each specialization ?

Regards,

Olivier

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: Template operator() overloading for types in a mpl::vector

by Steven Watanabe-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

AMDG

Olivier Tournaire wrote:

> I am currently trying to write a simple functor, and I would like to have
> the same overload for the operator () for all types in a mpl::vector.
>
> <snip>
>
> struct any_view_min_max
> {
>     typedef std::pair<float, float> result_type;
>
>     template <typename View>
>     result_type operator()(const View& v) const
>     {
>         typedef typename View::iterator iterator;
>         std::pair< iterator, iterator > result = boost::minmax_element(
> v.begin() , v.end() , pixel_compare_less() );
>         return std::make_pair( *(result.first) , *(result.second) );
>     }
> };
>
> This works fine for 'gray_image_types', but need to be specialized for types
> in rgb_image_types. The specialization is the same, so, I am looking for an
> automated way to do this. "Manually", I can write this:
>
> <snip>
>  

You can define two overloads of operator() and use enable_if to
distinguish them.

In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: Template operator() overloading for types in a mpl::vector

by Olivier Tournaire :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you Steven,

2009/11/2 Steven Watanabe <watanabesj@...>
AMDG

<snip>
 

You can define two overloads of operator() and use enable_if to
distinguish them.

I thought about this solution but did not know how to implement it. Could you please provide a small sample?
My current solution is to build mpl::vector from sequences and boost::preprocessor. Then, with BOOST_PP_SEQ_FOR_EACH I can automagically generate overloads for all types.

// image_types.hpp
#define RGB_IMAGE_TYPES (boost::gil::rgb8_image_t)(boost::gil::rgb16_image_t)(boost::gil::rgb32_image_t)
typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM( RGB_IMAGE_TYPES ) > rgb_image_types;
// ...

// min_max_functor.hpp
#define OVERLOAD_MIN_MAX_PARENTHESIS_OPERATOR( r , n , data ) template <> \
any_view_min_max::result_type any_view_min_max::operator()<data::view_t>(const data::view_t& v) const \
{ \
    // ...
}

BOOST_PP_SEQ_FOR_EACH( OVERLOAD_MIN_MAX_PARENTHESIS_OPERATOR , ~ , RGB_IMAGE_TYPES )

Regards,

Olivier
 


In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users


_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: Template operator() overloading for types in a mpl::vector

by Steven Watanabe-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

AMDG

Olivier Tournaire wrote:
> 2009/11/2 Steven Watanabe <watanabesj@...>
>  
>> You can define two overloads of operator() and use enable_if to
>> distinguish them.
>>    
> I thought about this solution but did not know how to implement it. Could
> you please provide a small sample?

typedef ... grey_image_types;
typedef ... rgb_image_types;

struct any_view_min_max {
    typedef ... result_type;
    template<class View>
    typename boost::enable_if<
        boost::mpl::contains<grey_image_types, View>,
    result_type>::type operator()(const View&);
    template<class View>
    typename boost::enable_if<
        boost::mpl::contains<rgb_image_types, View>,
    result_type>::type operator()(const View&);
};

In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: Template operator() overloading for types in a mpl::vector

by Olivier Tournaire :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thank you Steven for your reply. It works great.
Here is what I finally did:

// struct histogram_functor

    typename boost::enable_if< boost::mpl::contains< boost::mpl::transform<gray_image_types,add_view_type<boost::mpl::_1> >::type,
                                                     ViewType>,
                               result_type>::type operator()(const ViewType& v) const
    {
         // ...
    }

    template<class ViewType>
    typename boost::enable_if< boost::mpl::or_< boost::mpl::contains< boost::mpl::transform< rgb_image_types,
                                                                                             add_view_type<boost::mpl::_1 > >::type,
                                                                      ViewType>,
                                                boost::mpl::contains< boost::mpl::transform< rgba_image_types,
                                                                                             add_view_type<boost::mpl::_1 > >::type,
                                                                      ViewType>
                                              >,
                               result_type>::type operator()(const ViewType& v) const
    {
         // ...
    }

// ...
template <typename ImageType>
struct add_view_type
{
    typedef typename ImageType::view_t type;
};


However, I have one other need: type reduction. For instance, all rgb image types have the same overload operator(). I do not know if the solution I came up instantiate the operator for all types, but if it is the case, it is a valid but not a good solution. What I need is to have the same operator() for all rgb types. I have read in a paper from L .Bourdev (www.lubomir.org/academic/MinimizingCodeBloat.pdf) that I could use type reduction, but I need some help. Can you help ?
Here is the definition of rgb_image_types:
#define RGB_IMAGE_TYPES (boost::gil::rgb8_image_t)(boost::gil::rgb16_image_t)(boost::gil::rgb32_image_t)
typedef boost::mpl::vector< BOOST_PP_SEQ_ENUM( RGB_IMAGE_TYPES ) > rgb_image_types;

Best regards,

Olivier

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users