Boost logo

Boost Users :

From: Alan M. Carroll (amc_at_[hidden])
Date: 2005-08-28 11:50:28


I couldn't resist figuring out how to take advantage of boost::mpl::fold, which seemed very close to what I wanted. I've attached a (IMHO) superior version that takes better advantage of Boost.MPL. It uses only one adjunct struct, eliminating the extra functor class and being overall simpler and shorter. I ran this successfully using MSVC 71. I have to say, I can't imagine doing much better than this. MPL rocks.

At 05:19 PM 8/27/2005, you wrote:
Thanks!  I knew something like could be written, but for some reason I thought
there'd be significantly more overhead in turning a function into something
loopable.

It's unfortunate that one can't pass a function template as a template argument,
since that would remove the need for the extra functor class entirely.

# include <boost/mpl/list.hpp>
# include <boost/mpl/fold.hpp>

// The complicated function to call for each type.
// Top level template so it can be specialized in
// multiple locations.
template < typename T > void complicated_function( int i) {
    std::cout << "i = " << i << "  sizeof = " <<
sizeof (T) << std::endl;
}

// Support metafunction that adds a call to an existing
// chain of calls
struct chain {
   
template < typename R, // the accumulated chain
                     typename // a type from the list
                  > struct apply { // make this a Boost.MPL metafunction
        // the result from the application of the metafunction,
        // a functor that combines the chain in to one call.
        struct type {
           
void operator () (int i) const {
               
typename R()(i); // do the existing chain
                // add our type specialized call
                complicated_function< typename T>(i);
            }
        };
    };
   
// fold requires an initial state, for which we
    // provide this do nothing call. It's possible
    // optimize away the need for this but I think
    // that is more trouble than it is worth.
    struct no_op { void operator () (int i) const { return ; }};
};

void test_mpl() {
   
// create the list of types.
    typedef boost::mpl::list< int, char , float , std::string> the_list;
   
// create the chain of calls from the list
    typedef boost::mpl::fold<the_list, chain::no_op, chain>::type invocation;
   
// call the chain.
    invocation()(56);
}

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net