|
Boost Users : |
From: Gustavo Guerra (gustavobt_at_[hidden])
Date: 2001-12-18 21:22:53
----- Original Message -----
From: "Darin Adler" <darin_at_[hidden]>
> 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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net