----- Original Message ----- From: "Darin Adler" <darin@bentspoon.com>
The underlying issue is that you can't use a macro to define a macro. That just how the C and C++ language macros work.
So
#define X #define Y 1 X
will not allow you to define Y by invoking X. You'll just get a syntax error when the compiler sees the "#define" after expanding X.
I think the answer then is that it's just not possible, although there still may be some creative way to use the PREPROCESSOR library to help with what you are trying to do.
I has hoping that there was some obscure trick to make the preprocessor reprocess that part, but I guess not. So, I tried this, based on http://groups.yahoo.com/group/boost/message/21743 #include <boost/preprocessor/tuple.hpp> #include <boost/preprocessor/logical/not.hpp> #include <boost/preprocessor/comma.hpp> #include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/if.hpp> #include <boost/preprocessor/identity.hpp> #include <boost/preprocessor/empty.hpp> //---------------------- by Vesa Karvonen: ----------------------------------- #define BOOST_PREPROCESSOR_LIST_NIL (_,_,0) #define BOOST_PREPROCESSOR_LIST_CONS(H,T) (H,T,1) #define BOOST_PREPROCESSOR_LIST_IS_CONS(L) BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,L) #define BOOST_PREPROCESSOR_LIST_IS_NIL(L) BOOST_PREPROCESSOR_NOT(BOOST_PREPROCESSOR_TUPLE_ELEM(3,2,L)) #define BOOST_PREPROCESSOR_LIST_HEAD(L) BOOST_PREPROCESSOR_TUPLE_ELEM(3,0,L) #define BOOST_PREPROCESSOR_LIST_TAIL(L) BOOST_PREPROCESSOR_TUPLE_ELEM(3,1,L) //---------------------- by me: ------------------------- #define BOOST_PREPROCESSOR_LIST1(X) BOOST_PREPROCESSOR_LIST_CONS(X,\ BOOST_PREPROCESSOR_LIST_NIL) #define BOOST_PREPROCESSOR_LIST2(X,Y) BOOST_PREPROCESSOR_LIST_CONS(X,\ BOOST_PREPROCESSOR_LIST_CONS(Y,\ BOOST_PREPROCESSOR_LIST_NIL)) #define BOOST_PREPROCESSOR_LIST3(X,Y,Z) BOOST_PREPROCESSOR_LIST_CONS(X,\ BOOST_PREPROCESSOR_LIST_CONS(Y,\ BOOST_PREPROCESSOR_LIST_CONS(Z,\ BOOST_PREPROCESSOR_LIST_NIL))) #define BOOST_PREPROCESSOR_LIST4(X,Y,Z,W) BOOST_PREPROCESSOR_LIST_CONS(X,\ BOOST_PREPROCESSOR_LIST_CONS(Y,\ BOOST_PREPROCESSOR_LIST_CONS(Z,\ BOOST_PREPROCESSOR_LIST_CONS(W,\ BOOST_PREPROCESSOR_LIST_NIL)))) #define BOOST_PREPROCESSOR_LIST_IS_SIZE_1(L) \ BOOST_PREPROCESSOR_LIST_IS_NIL(BOOST_PREPROCESSOR_LIST_TAIL(L)) #define BOOST_PREPROCESSOR_LIST_FOR_EACH(LIST,P) \ BOOST_PREPROCESSOR_IF(BOOST_PREPROCESSOR_LIST_IS_NIL(LIST), \ P(BOOST_PREPROCESSOR_LIST_HEAD(LIST)), \ BOOST_PREPROCESSOR_LIST_FOR_EACH(BOOST_PREPROCESSOR_LIST_TAIL(LIST), P)) #define BOOST_PREPROCESSOR_LIST_ENUMERATE(LIST) \ BOOST_PREPROCESSOR_IF(BOOST_PREPROCESSOR_LIST_IS_SIZE_1(LIST), \ BOOST_PREPROCESSOR_LIST_HEAD(LIST), \ BOOST_PREPROCESSOR_LIST_ENUMERATE(BOOST_PREPROCESSOR_LIST_TAIL(LIST)) \ BOOST_PREPROCESSOR_COMMA) #define MAKE_FLAG_TYPE(TYPE_NAME, LIST) \ enum TYPE_NAME { BOOST_PREPROCESSOR_LIST_ENUMERATE(LIST) }; \ ::std::ostream& operator<<(::std::ostream& os, TYPE_NAME f) \ { \ switch(f) \ { \ BOOST_PREPROCESSOR_FOR_EACH(LIST, MAKE_FLAG_TYPE_AUX) \ } \ return os << "unknown"; \ } #define MAKE_FLAG_TYPE_AUX(ELEM) \ case ELEM: return os << BOOST_PREPROCESSOR_STRINGIZE(ELEM); This way, instead of writing something like this: MAKE_FLAG_TYPE4(event_type, read_event, write_event, timeout_event, error_event) I would have to write: MAKE_FLAG_TYPE(event_type, BOOST_PREPROCESSOR_LIST4(read_event, write_event, timeout_event, error_event)) But this still doesn't work. Neither BOOST_PREPROCESSOR_LIST_FOR_EACH(LIST,P) nor BOOST_PREPROCESSOR_LIST_ENUMERATE(LIST) work. I didn't even bother to test the rest. The problem seems to be that BOOST_PREPROCESSOR_IF doesn't call the else part. When I look at the preprocessed code of: BOOST_PREPROCESSOR_LIST_ENUMERATE(BOOST_PREPROCESSOR_LIST4(a,b,c,d)) I see something like: BOOST_PREPROCESSOR_LIST_ENUMERATE((b,(c,(d,(_,_,0),1),1),1)) BOOST_PREPROCESSOR_COMMA Although when I use BOOST_PREPROCESSOR_LIST_ENUMERATE(BOOST_PREPROCESSOR_LIST1(a)) I get a like expected What am I doing wrong? Gustavo Guerra