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