Server Levent Yilmaz wrote:
Take a look at this:
#define SPECIAL #define IS_SPECIAL(x) BOOST_PP_IS_EMPTY(BOOST_PP_EMPTY() x)
#define MACRO(i,z,array) IS_SPECIAL( BOOST_PP_ARRAY_ELEM(i, array) ) #define ENUM( n, tuple ) BOOST_PP_ENUM( n, MACRO, (n, tuple) )
ENUM( 3, ( arg1, , arg3) ) //1 ENUM( 3, ( arg1, SPECIAL, arg3) ) //2
In this context, can we safely say that 2 complies with standards more than 1?
No, because the argument to IS_SPECIAL (within MACRO) might expand to emptiness, anyway. #define MACRO(z,i,array) BOOST_PP_IS_EMPTY(BOOST_PP_EMPTY() \ BOOST_PP_ARRAY_ELEM(i,array) ) Is better, though still not correct: SPECIAL within 'array' expands to nothing before 'array' is passed to PP_ARRAY_ELEM. Now the problem occurs within the PP library. Now we'd have to know the exact number of expansions to defer the expansion of SPECIAL so many times that the final expansion to emptiness happens just within PP_IS_EMPTY: #define E() // Empty #define X(x) x // eXpand // demonstrate expansion gets deferred E E E E()()()() // E E E ()()() X( E E E E()()()() ) // E E () X(X( E E E E()()()() )) // E () X(X(X( E E E E()()()() ))) // #define SPECIAL E E E E E E E E E E E E E E E E E E E E E \ ()()()()()()()()()()()()()()()()()()()()() //#define MACRO(z,i,array) \ // BOOST_PP_IS_EMPTY( BOOST_PP_ARRAY_ELEM(i, array) ) #define MACRO(z,i,array) BOOST_PP_ARRAY_ELEM(i, array) #define ENUM( n, tuple ) BOOST_PP_ENUM( n, MACRO, (n, tuple) ) ENUM(3, (arg1, SPECIAL, arg3)) // arg1 , E () , arg3 This code works as expected with the GNU preprocessor. You can't rely on the number of expansions to be the same for another PP, since Boost.PP might have to correct PP misbehavior, taking a different "control path", for things to work at all. It's quite easy to cross the line messing with emptiness #define FOO(x) _ ## x #define BAR(x) FOO(x) FOO(BOOST_PP_EMPTY()) // OK, expands to _BOOST_PP_EMPTY() BAR(BOOST_PP_EMPTY()) // -undefined behavior- so ideally one finds a way not to have to mess with it at all, e.g: #define SAFE(optional) optional() #define STILL_SAFE(optional) SAFE(optional) SAFE(BOOST_PP_EMPTY) // expands to nothing SAFE(BOOST_PP_IDENTITY(xyz)) // xyz STILL_SAFE(BOOST_PP_EMPTY) // expands to nothing Regards, Tobias