----- Original Message -----
From: "Darin Adler"
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
#include
#include
#include
#include
#include
#include
//---------------------- 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