
On 4/26/2012 5:55 PM, Paul Mensonides wrote:
Implementation of the above attached--probably lots of room for improvement and optimization. Apologies for the mega function (in particular--I didn't feel like refactoring) and the (non-portable) shell color-coding (I wanted to see blue paint). I built it with g++ 4.7.0, but I believe 4.6+ should also work.
$ g++ -std=c++11 -I $CHAOS_ROOT 1.cpp
Updated attached. This one executes some more realistic tests. (I must say having no lexer to tokenize input and no parser to process directives makes input a pain in the ass.) #define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define INC(x) PRIMITIVE_CAT(INC_, x) #define INC_0 1 #define INC_1 2 #define INC_2 3 #define INC_3 4 #define INC_4 5 #define INC_5 6 #define INC_6 7 #define INC_7 8 #define INC_8 9 #define INC_9 9 #define DEC(x) PRIMITIVE_CAT(DEC_, x) #define DEC_0 0 #define DEC_1 0 #define DEC_2 1 #define DEC_3 2 #define DEC_4 3 #define DEC_5 4 #define DEC_6 5 #define DEC_7 6 #define DEC_8 7 #define DEC_9 8 #define EXPR_S(s) PRIMITIVE_CAT(EXPR_, s) #define EXPR_0(...) __VA_ARGS__ #define EXPR_1(...) __VA_ARGS__ #define EXPR_2(...) __VA_ARGS__ #define EXPR_3(...) __VA_ARGS__ #define EXPR_4(...) __VA_ARGS__ #define EXPR_5(...) __VA_ARGS__ #define EXPR_6(...) __VA_ARGS__ #define EXPR_7(...) __VA_ARGS__ #define EXPR_8(...) __VA_ARGS__ #define EXPR_9(...) __VA_ARGS__ #define SPLIT(i, ...) PRIMITIVE_CAT(SPLIT_, i)(, __VA_ARGS__) #define SPLIT_0(p, a, ...) p ## a #define SPLIT_1(p, a, ...) p ## __VA_ARGS__ #define IS_VARIADIC(...) \ SPLIT(0, CAT(IS_VARIADIC_, IS_VARIADIC_C __VA_ARGS__)) \ /**/ #define IS_VARIADIC_C(...) 1 #define IS_VARIADIC_IS_VARIADIC_C 0, #define IS_VARIADIC_1 1, #define NOT(x) IS_VARIADIC(PRIMITIVE_CAT(NOT_, x)) #define NOT_0 () #define COMPL(b) PRIMITIVE_CAT(COMPL_, b) #define COMPL_0 1 #define COMPL_1 0 #define BOOL(x) COMPL(NOT(x)) #define IIF(c) PRIMITIVE_CAT(IIF_, c) #define IIF_0(t, ...) __VA_ARGS__ #define IIF_1(t, ...) t #define IF(c) IIF(BOOL(c)) #define EMPTY() #define DEFER(id) id EMPTY() #define OBSTRUCT(id) id DEFER(EMPTY)() #define EAT(...) #define REPEAT_S(s, n, m, ...) \ IF(n)(REPEAT_I, EAT)(, OBSTRUCT(), INC(s), DEC(n), m, __VA_ARGS__) \ /**/ #define REPEAT_INDIRECT() REPEAT_S #define REPEAT_I(p, _, s, n, m, ...) \ EXPR_S _(s)( \ REPEAT_INDIRECT _()( \ s, n, p ## m, p ## __VA_ARGS__ \ ) \ p ## m _(s, n, p ## __VA_ARGS__) \ ) \ /**/ #define COMMA() , #define COMMA_IF(n) IF(n)(COMMA, EAT)() #define A(s, i, id) \ COMMA_IF(i) \ template<EXPR_S(s)(REPEAT_S(s, INC(i), B, ~))> class id ## i \ /**/ #define B(s, i, _) COMMA_IF(i) class EXPR_S(0)(REPEAT_S(0, 3, A, T)) The attached implementation yields correct results. g++ yields template< class> class T0 , template< class , class> class T1 , template< class , class , class> class T2 which is correct. wave yields template<class> class T0 , template<class , class> class T1 , template<class , class , class> class T2 which is correct. Unsurprisingly, VC++ errors. Regards, Paul Mensonides