
Hi Paul, Here are two questions regarding the BOOST_PP_IS_*ARY macros: My favourite use case is to allow macros to accept "user-friendly optional data structures". E.g: #define DO_UNARY(macro,x) \ BOOST_PP_IIF(BOOST_PP_IS_UNARY(x),macro,BOOST_PP_TUPLE_EAT(1))(x) #define DO_BINARY(macro,x) \ BOOST_PP_IIF(BOOST_PP_IS_BINARY(x),macro,BOOST_PP_TUPLE_EAT(1))(x) DO_UNARY(A_MACRO,(elem)) // passes '(elem)' to A_MACRO DO_UNARY(A_MACRO,-) // expands to nothing DO_BINARY(ANOTHER_MACRO,(x,y)) // passes '(x,y)' to ANOTHER_MACRO DO_BINARY(ANOTHER_MACRO,-) // expands to nothing or (the inverse logic for "non-generic scalar" arguments) #define OPTIONAL(x) \ BOOST_PP_IIF(BOOST_PP_IS_UNARY(x),BOOST_PP_TUPLE_EAT(1), \ BOOST_PP_TUPLE_REM(1))(x) OPTIONAL(foo) // expands to 'foo' OPTIONAL( (none) ) // expands to nothing . Is it safe to use this technique with sequences, e.g. #define OPT_SEQ_CAT(seq) \ BOOST_PP_IIF(BOOST_PP_IS_UNARY(seq),BOOST_PP_SEQ_CAT, \ BOOST_PP_TUPLE_EAT(1))(seq) OPT_SEQ_CAT(-) // expands to nothing OPT_SEQ_CAT((b)(o)(o)(s)(t)) // expands to 'boost' ?! And why do these components live in 'detail' (as opposed to 'tuple')? Because of Borland? Thanks, Tobias ( Includes to preprocess the code in this post: #include <boost/preprocessor/seq/cat.hpp> #include <boost/preprocessor/tuple/eat.hpp> #include <boost/preprocessor/tuple/rem.hpp> #include <boost/preprocessor/control/iif.hpp> #include <boost/preprocessor/detail/is_unary.hpp> #include <boost/preprocessor/detail/is_binary.hpp> )