I'm trying to get the OS and compiler name as a string in C++. Although there are many questions about this I did not find a definitive answer. So I tried to use Boost.Predef 1.55 which defines macros of the type BOOST_OS_<OS> and BOOST_OS_<OS>_NAME.
Hence one could simply do if(BOOST_OS_<OS>) return BOOST_OS_<OS>_NAME; for every OS boost supports. Same for compilers with COMP instead of OS. To avoid the repetition I wanted to use Boost.Preprocessor and put them all in a loop.
What I came up with is this:
#define MAKE_STMT_I2(PREFIX) if(PREFIX) return PREFIX ## _NAME;
#define MAKE_STMT_I(type, curName) MAKE_STMT_I2(BOOST_ ## type ## _ ## curName)
#define MAKE_STMT(s, type, curName) MAKE_STMT_I(type, curName)
#define OS_LIST (AIX)(AMIGAOS)(ANDROID)(BEOS)(BSD)(CYGWIN)(HPUX)(IRIX)(LINUX)(MACOS)(OS400)(QNX)(SOLARIS)(UNIX)(SVR4)(VMS)(WINDOWS)(BSDI)(DRAGONFLY)(BSD_FREE)(BSD_NET)(BSD_OPEN)
BOOST_PP_SEQ_FOR_EACH(MAKE_STMT, OS, OS_LIST)
However I run into problems where the values are expanded to soon. E.g. VMS defines already a macro named VMS which then gets replaced in OS_LIST. Even doing something like #define OS_LIST (##AIX##)(##AMIGAOS##)(... does not help as it seems to get expanded in boost later.
How can I avoid the expansion in the sequence completely?