
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