Re: [Boost-users] Template operator() overloading for types in a
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 ?
Your situation seems similar to the one discussed here: http://stackoverflow.com/questions/1492204/is-it-possible-to-generate-ty pes-with-all-combinations-of-template-arguments. I actually refined the idea and modeled the mpl::for_each, and came up with this code pasted below for your reference.What you need to modify is to reduce the template arguments from 3 to 2 to suit your needs, hope it helps. #ifndef FOR_EACH_CARTESIAN_PRODUCT_H #define FOR_EACH_CARTESIAN_PRODUCT_H #include <boost/mpl/vector.hpp> #include <boost/mpl/begin.hpp> #include <boost/mpl/end.hpp> #include <boost/mpl/deref.hpp> #include <boost/type_traits/is_integral.hpp> #include <iostream> #include <typeinfo> /* usage 1: typedef recursive::for_each_cartesian-product< stock::map_containers, stock::shrinker_equal_filters, stock::shrinker_method_tags, RunnableBody > benchmark_type; benchmark_type::run_all(); usage 2: typedef recursive::for_each_cartesian-product< stock::map_containers, stock::shrinker_equal_filters, stock::shrinker_method_tags, RunnableBody >::each_product<> benchmark_type; benchmark_type::run(); */ namespace recursive { using boost::is_same; using boost::is_integral; using boost::mpl::begin; using boost::mpl::end; using boost::mpl::next; using boost::mpl::if_; using boost::mpl::deref; using boost::mpl::size; using boost::mpl::advance; using boost::mpl::distance; using boost::mpl::int_; using boost::mpl::eval_if_c; namespace detail { static unsigned int total_recursions = 0; } // generate a Cartesian Product of 3 type sequences and apply RunnableBody on each generated type template < class UTypes, // Forward Sequence, e.g. boost::mpl::vector class VTypes, // Forward Sequence, e.g. boost::mpl::vector class WTypes, // Forward Sequence, e.g. boost::mpl::vector class RunnableBody // class type that has a nested templated run() member function > struct for_each_cartesian_product { // forward declaration template < class UIterator, class VIterator, class WIterator > class each_product; struct end_of_recursion_tag { static void run(RunnableBody& f) { #ifndef NDEBUG std::cout << "End of " << detail::total_recursions << " recursions: RunnableBody = " << typeid(RunnableBody).name() << std::endl; #endif detail::total_recursions = 0; } }; // convenient interface to run RunnableBody on all generated types static void run_all(RunnableBody& f = RunnableBody()) { each_product<>::run(f); } // this class implements recursion body template < class UIterator, class VIterator, class WIterator > struct next_product { // u_begin is not necessary ;) // it would be cheaper not to pre-declare all of them since we force evaluation // however this dramatically increase the readability typedef typename begin<VTypes>::type v_begin; typedef typename begin<WTypes>::type w_begin; typedef typename end<UTypes>::type u_end; typedef typename end<VTypes>::type v_end; typedef typename end<WTypes>::type w_end; typedef typename next<UIterator>::type u_next; typedef typename next<VIterator>::type v_next; typedef typename next<WIterator>::type w_next; typedef typename if_< is_same<typename w_next, w_end>, typename if_< is_same<v_next, v_end>, typename if_< is_same<u_next, u_end>, end_of_recursion_tag, each_product< u_next, v_begin, w_begin > >::type, each_product< UIterator, v_next, w_begin > >::type, each_product< UIterator, VIterator, w_next > >::type type; }; // interface // this class run test on generated types in thos round and go to next*/ template < class UIterator = typename begin<UTypes>::type, class VIterator = typename begin<VTypes>::type, class WIterator = typename begin<WTypes>::type > struct each_product { // publc accessible internals of this type typedef typename each_product< UIterator, VIterator, WIterator > this_type; // types typedef typename deref<UIterator>::type UType; typedef typename deref<VIterator>::type VType; typedef typename deref<WIterator>::type WType; // index types typedef typename distance<typename begin<UTypes>::type, UIterator>::type UIndexType; typedef typename distance<typename begin<VTypes>::type, VIterator>::type VIndexType; typedef typename distance<typename begin<WTypes>::type, WIterator>::type WIndexType; // core static void run(RunnableBody& f = RunnableBody()) { // increment recursion counter ++detail::total_recursions; //f.template <this_type>(); f.operator()<this_type>(); // generate <<next>> target type and go to the next round of recursion typedef typename next_product< UIterator, VIterator, WIterator >::type next_type; next_type::run(f); } }; // alternative interface template < size_t UIndex = 0, size_t VIndex = 0, size_t WIndex = 0 > struct each_product_by_index { static_assert(UIndex <= size<UTypes>::type::value, "too large stock container index"); static_assert(VIndex <= size<VTypes>::type::value, "too large stock shrinker_group_number index"); static_assert(WIndex <= size<WTypes>::type::value, "too large stock shrinker_group_size index"); typedef typename begin<UTypes>::type u_begin; typedef typename begin<VTypes>::type v_begin; typedef typename begin<WTypes>::type w_begin; static void run(RunnableBody& f = RunnableBody()) { // delegate to iterator-version each_product< typename advance<u_begin, int_<UIndex> >::type, typename advance<v_begin, int_<VIndex> >::type, typename advance<w_begin, int_<WIndex> >::type >::run(f); } }; }; // an example test function class impl. struct print_typeid { template< class T> void operator()() const { typedef typename T::UType U; typedef typename T::VType V; typedef typename T::WType W; typedef typename T::UIndexType UIndex; typedef typename T::VIndexType VIndex; typedef typename T::WIndexType WIndex; // print the typeinfo std::cout << "this is a demo implementation.\n"; std::cout << detail::total_recursions << "[" << UIndex::value ", " << VIndex::value ", " << WIndex::value << "]" << ": " << typeid(U).name() << "," << typeid(V).name() << "," << typeid(W).name() << std::endl; } }; }// namespace recursive_test
participants (1)
-
Tan, Tom (Shanghai)