Boost logo

Boost :

Subject: [boost] Alternative implementation for BOOST_PP_VARIADIC_SIZE
From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2011-11-10 18:43:02


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?

Regards,
Gennadiy


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk