$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Help with Boost Preprocessor
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-08-29 21:34:41
AMDG
Emil Dotchevski wrote:
> Let's say I have a class template functor like this:
>
> struct
> func
>     {
>     typedef void result_type;
>
>     template <class A1,class A2,class A3>
>     void
>     operator()( A1, A2, A3, int x )
>         {
>         }
>     };
>
> Given a list of types, I want the function instantiated and called for
> all permutations of the types in the list; the additional argument(s),
> x, just need to be forwarded the same for all instances.
>
> Actually I got it working, see http://codepad.org/tnYTy9Iw.
>
> I don't think that my solution is very good though. First, it has some
> run-time overhead due to the use of boost::bind in fwd1 and fwd2 (see
> link above.) Second, I'd like the macro that defines the type list not
> to be hard-coded in fwd1 and fwd2.
>
> Is this possible?
>   
How does this work
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <iostream>
struct
func
    {
    typedef void result_type;
    template <class A1,class A2,class A3>
    void
    operator()( A1, A2, A3, int x )
        {        std::cout <<
            typeid(A1).name() << ',' <<
            typeid(A2).name() << ',' <<
            typeid(A3).name() << ',' <<
            x << '\n';
        }
    };
template<class T>
T make() { return T(); }
#define CALL_FUNC(r, args) func()(BOOST_PP_SEQ_ENUM(args), x);
#define MAKE_OBJECT(s, data, elem) make<elem>()
#define FUNC_II(types) \
    BOOST_PP_SEQ_FOR_EACH_PRODUCT(CALL_FUNC, (types)(types)(types))
#define FUNC_I(types) FUNC_II(types)
#define FUNC(types, arg)                                        \
    if(true) {                                                  \
        int x = arg;                                            \
        FUNC_I(BOOST_PP_SEQ_TRANSFORM(MAKE_OBJECT, ~, types))   \
    } else ((void)0)
int main() {
    FUNC((int)(long), 42);
}
In Christ,
Steven Watanabe