arlo on 11 Jun 2003 23:12:01 -0000 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: [ALACPP] Meeting |
Have you seen boost's preprocessor library? They've defined a bunch of these types of macros for you - may be handy the next time that you're trying to do something like this. For example, they have several looping constructs (yes, with the C preprocessor), the usual FP elements (usually as higher order macros), and a few really nifty items like file iteration (a file is effectively a function, and you can, eg, request FOR(1, 35, include baz), then access the value of the loop index within the file. It also has a bunch of constructs for handling variable numbers of args, and the like. I make very heavy use of it when I want to template something on "any set of types of arbitrary size" or "any number of args of arbitrary types", which is pretty common. Arlo (your local boost pusher) > So far this is all pretty straightforward for functors with only one > argument. But the preprocessor mumbo-jumbo comes into play when we want > to handle functors with an arbitrary number of arguments (actually up > to 15). We need facilities to manipulate lists of types, analogous to > Loki::Typelists. > > The macros SKIP(), TAKE(), and MAP() are designed to manipulate lists > of types. SKIP(n, ...) has a number and a list as input, and returns > the list without the first n elements. TAKE(n, ...) has a number and a > list as input and returns the first n elements of the list. MAP() the > workhorse. MAP() is a higher-order macro, thats a macro that has the > name of another macro as an argument. MAP(f, n, ...) applies the macro > f to each of the n remaining arguments, one at a time, while > concatenating the results together. This is possible because the rules > the preprocessor follows for expanding macros. Since the f macro takes > arguments itself, it will not be expanded by the preprocessor until it > is placed in-front of a pair of parenthesis. In effect delaying the > evaluation of f until we apply it to an argument. > > There is another preprocessing trick we use to get primitive flow > control in a macro. Assume some macro has a parameter named n that is > always an integer. Now this macro calls another macro named f with the > expression f##n(). The concatenate operator (##) combines two tokens to > form one token. So if f is SKIP, and n is 3, then f##n(x) expands to > SKIP3(x), which is then further expanded by the preprocessor according > to the definition of SKIP3(). To recap, we have selected a macro from > an indexed family of macros, based on a parameter passed in by the > caller. This is the preprocessor version of a switch statement, or a > function lookup table. > > -Josh Dybnis > _______________________________________________ > alacpp mailing list > alacpp@xxxxxxxxxxx > http://lists.ellipsis.cx/mailman/listinfo/alacpp > _______________________________________________ alacpp mailing list alacpp@xxxxxxxxxxx http://lists.ellipsis.cx/mailman/listinfo/alacpp