Re: Template operator() overloading for types in a

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

Parent Message unknown Re: Template operator() overloading for types in a

by Tan, Tom (Shanghai) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>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
_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users