On Sun, Aug 28, 2005 at 11:50:28AM -0500, Alan M. Carroll wrote:
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.
Alas, eliminating the extra functor that way doesn't help, since in my case I have to apply this construct to a slew of functions (this is for a water simulator where we often have to do something for x,y in 2d or x,y,z in 3d). Happily, the annoyance of the extra helper structs is nothing in comparison to the fact that this let me replace 18 source files with 6 (2/3's of the files were 2d/3d stubs). Thanks, Geoffrey
# include
# include // 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 T // 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
::type invocation; // call the chain. invocation()(56); }