Boost logo

Boost :

Subject: Re: [boost] [preprocessor] Variadics suggestion
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2012-09-25 03:45:54


On Mon, 24 Sep 2012 16:15:34 -0400, Kitten, Nicholas wrote:

> Hi Folks,
>
> First of all, I'd like to say "thank you" to Edward Diener and Paul
> Mensonides for incorporating variadics support into Boost.Preprocessor,
> which has been on my wishlist for a long time.
>
> In fact, I wanted it badly enough that I've been using my own slightly
> modified version of the library assuming variadics for a while now, and
> I was interested to see what a cross-platform version would look like
> (mine was only tested on MSVC). I think the chosen approach of
> converting variadics to non-variadics is probably superior to the
> breaking algorithm changes I made in my own version, and I would humbly
> suggest a few more additions in the same spirit.

Get a good preprocessor (such as Wave or a different compiler) and use
Chaos. Bad preprocessors are precisely the reason that Boost.Preprocessor
is not much more functional than it is.

> The reason I chose to use variadics in the first place was to simplify
> the user interface for the common case of manipulating what I'll call a
> "variadic sequence," (a series of concatenated tuples), which I wanted
> to look similar to the following:
>
> #define FILTER_PARAMETERS (A, int, 3)\
> (B, float, 2.0f)\
> (C, const char*,
> "Howdy!")

Chaos calls (1, 2, ..., n)(1, 2, ..., n) an n-ary sequence. It calls (1)
(1, 2)(1, 2, 3)(1, 2)(1) a variadic sequence. It has first-class support
for both. E.g. for a binary sequence:

#define A(s, a, b) a + b
#define B(s, a, b, x) a + b + x
#define C(x, a, b, x, y) a + b + x + y

CHAOS_PP_SEQ_AUTO_FOR_EACH(A, (a, b)(p, q)(x, y))
CHAOS_PP_SEQ_AUTO_FOR_EACH(B, (a, b)(p, q)(x, y), z)
CHAOS_PP_SEQ_AUTO_FOR_EACH(C, (a, b)(p, q)(x, y), z, w)

> #define SEQ (a,b,c)(1,2,3,4)
> BOOST_PP_VARIADIC_SEQ_TO_SEQ( SEQ ) // expands to
> ((a,b,c))((1,2,3,4))

This is probably doable.

> I'm submitting this because I couldn't find a way to use some
> combination of TUPLE/VARIADICS and SEQ transformations to do the same
> thing succinctly, but if I'm just missing something, please let me know.
>
> Next, I would suggest having a documented IS_EMPTY(...) function for
> detecting an empty variadic list. Since is_empty.hpp already exists for
> single arguments (though undocumented), I would guess the variadic
> version would look quite similar. My own (MSVC) version is attached.

No. Your implementation causes undefined behavior which happens to work
on VC++.

There is no way to make a general-purpose emptiness-detection macro. The
closest you can get is to restrict the domain to arguments which do not
end in function-like macro names.

> Finally, I would suggest using the preceding IS_EMPTY(...) function to
> allow VARIADIC_SIZE(...) to return 0, i.e. something along the lines of:

Again, no. Emptiness is a valid argument. E.g.

VARIADIC_SIZE() // 1
VARIADIC_SIZE(,) // 2
VARIADIC_SIZE(,,) // 3

Not only is this the nature of the preprocessor, an example use case would
be cv-qualifiers. E.g.

()(const)(volatile)(const volatile)

This is a unary sequence. Each element is a value of type "cv-qualifier".

Any time that you want to consider emptiness as zero arguments is a
special case, not the general case. Moreover, you can only do so when the
above domain restriction on IS_EMPTY is known to be viable.

Regards,
Paul Mensonides


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