
On 11/10/2011 6:43 PM, Gennadiy Rozental wrote:
Hi,
Current implementation of subject macro have a very serious shortcoming - it does not work for empty __VA_ARGS__. After googling around a bit for some ideas I came up with the following alternative:
#include<boost/preprocessor/arithmetic/mul.hpp> #include<boost/preprocessor/arithmetic/sub.hpp> #include<boost/preprocessor/punctuation/comma.hpp>
#define MY_VA_ARG_N( \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _61,_62,_63, N, ...) N
#define MY_VA_RSEQ_N() \ 63,62,61,60, \ 59,58,57,56,55,54,53,52,51,50, \ 49,48,47,46,45,44,43,42,41,40, \ 39,38,37,36,35,34,33,32,31,30, \ 29,28,27,26,25,24,23,22,21,20, \ 19,18,17,16,15,14,13,12,11,10, \ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define MY_DO_VA_NARG2(...) MY_VA_ARG_N __VA_ARGS__ #define MY_DO_VA_NARG(...) MY_DO_VA_NARG2(( __VA_ARGS__ ))
// this version produces incorrect value (1) for empty __VA_ARGS__ #define MY_VA_NARG_(...) MY_DO_VA_NARG(__VA_ARGS__, MY_VA_RSEQ_N())
// this version fixes it #define MY_VA_NARG(...) BOOST_PP_SUB( BOOST_PP_MUL( MY_VA_NARG_( __VA_ARGS__ ), 2 ), MY_VA_NARG_( BOOST_PP_COMMA __VA_ARGS__ () ) )
This version work for zero sized __VA_ARGS__ and also works for MSVC-9,10 , gcc-4.1 gcc 3.2 (did not test with other compilers).
Does it make sense to improve trunk version?
I will look at this but please look at my variadic macro data library in the sandbox which attempts to solve this same problem. When I announced the latest update to my library, nobody paid any attention to it.