Boost logo

Boost :

From: Josh Dybnis (jdybnis_at_[hidden])
Date: 2003-06-26 17:27:55


> It isn't that it isn't worthwhile to support them. Rather, it is
> because there are already about three (on average) different
> implementations of the pp-lib to work around various (sometimes
> serious) compiler deficiencies. Supporting variadics and
> placemarkers from C99 would add, at minimum, two more versions of
> about half the library. That's why I don't want to support
> a "variadic" mode in general in the pp-lib at this point. However,
> that isn't why I don't want to add support for variadic parameters as

> a data type. (I'll address that below in more detail.)

That seems justified, since it does not seem like my idea of
implementing variadics using a thin layer over the existing library
will work.

> it doesn't directly support variadics as a data structure. The
> reasons for this are simple: 1) Variadic data can contain open
> commas and that interferes with parameter lists if you need to pass
> around more than one structure or if you need to use the variadic
> argument for something else.

Very true, but in the common case you just have 1 variadic list. In the
remaining cases you must require the extra parenthisis. For the
implementation I posted, that only occurs within internal library
calls, and the extra parenthisis are not required in the interface.

> 2) There is no way (without resorting to undefined behavior)
> of detecting whether you're at the end of the variadic parameters.
> There are only two reasonable ways to do it: First, make an "end"
> rogue value that is pathological but detectable as opposed to any
> other possible input ... second, limit the number of variadic
> parameters.

It seems to me that "empty" is a close enough approximation to "end of
the parameters," in practice. Here is an implementation of IS_EMPTY
that I don't think relies on any undefined behavior. With two caveats:

1) it cannot differenciate between foo(a,) and foo(a) where foo is:

#define foo(x, ...) BOOST_PP_VA_IS_EMPTY(__VA_ARGS__)

2) it causes most compilers to spit out a warning if the final
parameter ends in the name of a function-like macro. e.g.:

foo(a, BOOST_PP_CAT) /* causes a warning message */

That said, here is the implementaion:

#define BOOST_PP_VA_IS_EMPTY(...) \
    BOOST_PP_VA_HEAD \
    ( BOOST_PP_VA_CAT1 \
        ( BOOST_PP_VA_IS_EMPTY_, \
            BOOST_PP_VA_CAT1 \
            ( BOOST_PP_VA_IS_EMPTY_, \
                BOOST_PP_VA_IS_EMPTY_EAT __VA_ARGS__ \
            ) () \
        ) \
   )

#define BOOST_PP_VA_IS_EMPTY_EAT(...) BOOST_PP_VA_IS_EMPTY_EATEN
#define BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_EAT() \
    BOOST_PP_VA_IS_EMPTY_EMPTY
#define BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_EATEN \
    BOOST_PP_VA_IS_EMPTY_NOT_EMPTY
#define BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_EMPTY 1,
#define BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_NOT_EMPTY 0,
#define
BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_BOOST_PP_VA_IS_EMPTY_EAT 0,

#define BOOST_PP_VA_CAT1(...) BOOST_PP_VA_CAT1_I(__VA_ARGS__)
#define BOOST_PP_VA_CAT1_I(x, ...) x ## __VA_ARGS__

-Josh Dybnis


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