|
Boost : |
From: Arias Brent-P96059 (Brent.Arias_at_[hidden])
Date: 2004-11-19 12:06:43
>Not a bug. Empty macro arguments are currently undefined behavior in C++.
There is nothing that I can do about that. C99 added explicit support for them, but they are not (yet) part of C++.
I very much appreciate your answer. And ultimately this hasn't become a big deal, since - as you saw - I found a way around the problem all the same.
But now let me answer a very good question you asked:
> #define ENUM(name, start, entries)\
> BOOST_PP_SEQ_ENUM( \
> BOOST_PP_IIF(ENUMS, \
> (typedef enum{ BOOST_PP_SEQ_HEAD(entries) = start) \
> BOOST_PP_SEQ_TAIL(entries) \
> (LAST_##name } name;) \
> , \
> (static void PP_NILFUNC();) \
> ) \
> )
>Why are you doing the test *inside* of the invocation of SEQ_ENUM?
The short answer: I wanted a **single** ENUM macro definition that permitted the printable strings *AND* the enums themselves to be conditionally compileable.
I think my intention will make more sense if I show you the entire printable enum. It looks like this:
#ifndef ENUMS /*By default, turn enums on*/
#define ENUMS 1
#endif
#ifndef ESTRINGS /*By default, turn printable strings on*/
#define ESTRINGS 1
#endif
#ifndef EDEBUG
#define EDEBUG 0 /*By default, turn ESTRINGS "compliment" condition off */
#endif
/*Used internally by the ENUM macro*/
#ifdef ENUM_STR
#undef ENUM_STR
#endif
#define ENUM_STR(r, data, elem) BOOST_PP_STRINGIZE(elem)
#define ENUM(name, start, entries) \
BOOST_PP_SEQ_ENUM( \
BOOST_PP_IIF(ENUMS, \
(typedef enum{ BOOST_PP_SEQ_HEAD(entries) = start) \
BOOST_PP_SEQ_TAIL(entries) \
(LAST_##name } name;) \
, \
(static void PP_NILFUNC();) \
) \
) \
BOOST_PP_SEQ_ENUM( \
BOOST_PP_IIF(BOOST_PP_BITOR(EDEBUG,ESTRINGS), \
(static const char* name##_Str[]={ BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(entries)) ) \
BOOST_PP_SEQ_TRANSFORM(ENUM_STR, _, BOOST_PP_SEQ_TAIL(entries) ) \
(};) \
, \
(static void PP_NILFUNC();) \
) \
)
Now, as I think you pointed out yourself, you can't place the BOOST_PP_SEQ_ENUM inside of a BOOST_PP_EXPR_IIF statement like this:
#define ENUM(name, start, entries) \
BOOST_PP_EXPR_IIF(ENUMS)( \
BOOST_PP_SEQ_ENUM( \
(typedef enum { BOOST_PP_SEQ_HEAD(entries) = start) \
BOOST_PP_SEQ_TAIL(entries) \
(LAST_ ## name } name;) \
) \
) \
So, what I've shown you in the printable enum above was the only solution I could think of to achieve the result: i.e. a **single** ENUM macro definition that permitted the printable strings *AND* the enums themselves to be conditionally compileable.
On the other hand, I'm intrigued with what you presented here:
#define ENUM(name, start, entries) \
BOOST_PP_IIF( \
ENUMS, \
BOOST_PP_SEQ_ENUM, BOOST_PP_TUPLE_EAT(1) \
)( \
(typedef enum { BOOST_PP_SEQ_HEAD(entries) = start) \
BOOST_PP_SEQ_TAIL(entries) \
(LAST_ ## name } name;) \
) \
I didn't pay attention to BOOST_PP_TUPLE_EAT when I was (frantically) trying to make a printable enum. Perhaps it is a means by which I can get rid of the "hack" I described earlier? It sure looks like it will work!
Oh, by the way, I was so pleased with the printable enum - I was actually thinking of submitting it for inclusion into Boost. Would a submission like that be more nuisance than benefit?
Thanks,
-Brent
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk