
On Wed, 24 Nov 2010 14:45:02 -0800, Jeffrey Lee Hellrung, Jr. wrote:
On 11/24/2010 2:14 PM, Edward Diener wrote: [...]
I am still not sure what you mean by "macro composition" and "argument binding" in a preprocessor library. Boost PP has much support for macro composition within the context of what it offers in the form of repeatable constructs, data types, etc. but I have a feeling you mean something else. As far as "argument binding", in terms of preprocessor macros all arguments are initially in the form of tokens, so I am not sure what you mean by the phrase.
Imagine Boost.MPL without placeholders.
As a simple example, suppose you already have a macro handy:
#define macro( n ) ...insert your favorite expression involving n...
and want to use it in an invocation of BOOST_PP_ENUM. This requires defining a forwarding macro:
#define macro2( z, n, data ) macro( n ) BOOST_PP_ENUM( N, macro2, ~ )
Argument binding refers to the ability to bind the arguments of function-style macros to tokens or placeholders for tokens to be substituted later. So one would be able to do something like (making up the syntax from what I can remember)
BOOST_PP_ENUM( N, BIND( macro, 2 ), ~ )
For what it's worth, with the way that Chaos invokes user-supplied macros, it isn't difficult to provide general-purpose argument mappers. The general form would be something like (for only three arguments)... #define MAP(...) CHAOS_PP_VARIADIC_CAT(MAP_, __VA_ARGS__) #define UNARY_MAP(n, ...) \ ( \ CHAOS_PP_VARIADIC_ELEM(n, __VA_ARGS__) \ ) \ /**/ #define MAP_0(...) UNARY_MAP(0, __VA_ARGS__) #define MAP_1(...) UNARY_MAP(1, __VA_ARGS__) #define MAP_2(...) UNARY_MAP(2, __VA_ARGS__) #define BINARY_MAP(n, m, ...) \ ( \ CHAOS_PP_VARIADIC_ELEM(n, __VA_ARGS__), \ CHAOS_PP_VARIADIC_ELEM(m, __VA_ARGS__) \ ) \ /**/ #define MAP_01(...) BINARY_MAP(0, 1, __VA_ARGS__) #define MAP_02(...) BINARY_MAP(0, 2, __VA_ARGS__) #define MAP_10(...) BINARY_MAP(1, 0, __VA_ARGS__) #define MAP_12(...) BINARY_MAP(1, 2, __VA_ARGS__) #define MAP_20(...) BINARY_MAP(2, 0, __VA_ARGS__) #define MAP_21(...) BINARY_MAP(2, 1, __VA_ARGS__) #define TERNARY_MAP(n, m, o, ...) \ ( \ CHAOS_PP_VARIADIC_ELEM(n, __VA_ARGS__), \ CHAOS_PP_VARIADIC_ELEM(m, __VA_ARGS__), \ CHAOS_PP_VARIADIC_ELEM(o, __VA_ARGS__) \ ) \ /**/ #define MAP_012(...) TERNARY_MAP(0, 1, 2, __VA_ARGS__) #define MAP_021(...) TERNARY_MAP(0, 2, 1, __VA_ARGS__) #define MAP_102(...) TERNARY_MAP(1, 0, 2, __VA_ARGS__) #define MAP_120(...) TERNARY_MAP(1, 2, 0, __VA_ARGS__) #define MAP_201(...) TERNARY_MAP(2, 0, 1, __VA_ARGS__) #define MAP_210(...) TERNARY_MAP(2, 1, 0, __VA_ARGS__) #define A(n) n CHAOS_PP_EXPR(CHAOS_PP_ENUM( 10, A MAP(1) )) #define B(c, n) n / c CHAOS_PP_EXPR(CHAOS_PP_ENUM( 10, B MAP(2, 1), 2 )) This, of course, is a combinatorial implementation, but for relatively low numbers of arguments, it isn't too bad. Regards, Paul Mensonides