Template operator() overloading for types in a mpl::vector
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
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
Thank you Steven, 2009/11/2 Steven Watanabe <watanabesj@gmail.com>
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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
AMDG Olivier Tournaire wrote:
2009/11/2 Steven Watanabe <watanabesj@gmail.com>
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
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/Minimizing*CodeBloat*.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
participants (2)
-
Olivier Tournaire
-
Steven Watanabe