
On 2/19/2011 10:48 AM, Lorenzo Caminiti wrote:
On Fri, Feb 18, 2011 at 9:58 PM, Edward Diener<eldiener@tropicsoft.com> wrote:
On 2/18/2011 7:27 PM, Lorenzo Caminiti wrote:
On Thu, Feb 17, 2011 at 5:13 PM, Edward Diener<eldiener@tropicsoft.com> wrote:
I am requesting that my library, the Variadic Macro Data library, which is in the sandbox in the variadic_macro_data directory, be reviewed for inclusion into Boost.
The variadic_macro_data library adds support and functionality for variadic macros to Boost as well as integrating variadic macros with the Boost PP library without changing the latter library in any way.
I believe others have used my library, can attest to its quality and that it does what it is supposed to do. and have found it useful when using variadic macros with Boost PP. I myself have used its functionality in my own TTI library in the sandbox. Support for variadic macros is implemented in nearly all modern C++ compilers and the syntax is natural for an end-user. The library is finalized as far as functionality is concerned and I would like to see it in Boost and am willing to maintain it as a Boost library.
Is it possible to use variadic macros to detect empty parameters?
My understanding of variadic macro data is that at least one parameter must be specified.
For example:
#include<boost/variadic_macro_data/VariadicMacroData.hpp> // Proposed lib.
VMD_DATA_SIZE(1, 2) // 2 VMD_DATA_SIZE(1) // 1 VMD_DATA_SIZE() // 1 not 0 :((
But I would like to the last size to expand to 0 (or have a different macro that would expand to 0 in that case).
With a real C99 preprocessor (e.g., GCC) I can do the following because empty macro parameters are supported:
Are they for variadic macro data in C++ ?
I think variadics and empty macro parameters are different things. C99 preprocessor (e.g., GCC) supports both while MSVC only supports variadics. That is why I was wondering if variadics can be used to detect empty macro parameters so I can do so also on MSVC.
On Mon, Sep 6, 2010 at 3:29 PM, Paul Mensonides<pmenso57@comcast.net> wrote:
... However, IS_EMPTY is _not_ a macro for general-purpose emptiness detection. Its implementation requires the concatenation of an identifier to the front of the argument which rules out all arguments for which that isn't valid. For example, IS_EMPTY(+) is undefined behavior according to all revisions of both the C and C++ standards (including the forthcoming C++0x). Thus, at minimum, the argument must be an identifier (or keyword--same thing at this point) or a numeric literal that doesn't contain a decimal point.
It is valid (and has been since C90) to pass something that expands to nothing as an argument to a macro. However, it is not valid to pass nothing. E.g.
See http://lists.boost.org/Archives/boost/2010/09/170639.php
Thanks for the clarification.
I will look at that and see what I can come up with. If variadic macros support an empty parameter list, I should provide a correct size of 0. If it does not I should indicate an error. So either way I will look to make a correction. Thanks for pointing this out.
This works on both MSVC and GCC :) Does it work on other preprocessors? Can anyone please check?
#include<boost/variadic_macro_data/VariadicMacroData.hpp> // Proposed lib in Boost's sandbox. #include<boost/preprocessor.hpp> #include<boost/preprocessor/facilities/is_empty.hpp>
VMD_DATA_SIZE(1, 2) // 2 VMD_DATA_SIZE(1) // 1 VMD_DATA_SIZE() // 1 not 0 :((
#define PP_VA_EAT(...) /* must expand to nothing */
#define PP_VA_SIZE_1OR0_(maybe_empty) \ BOOST_PP_IIF(BOOST_PP_IS_EMPTY(maybe_empty (/*exapnd empty */) ), 0, 1)
#define PP_VA_SIZE_(size, ...) \ BOOST_PP_IIF(BOOST_PP_EQUAL(size, 1), \ PP_VA_SIZE_1OR0_ \ , \ size PP_VA_EAT \ )(__VA_ARGS__ BOOST_PP_EMPTY)
#define PP_VA_SIZE(...) PP_VA_SIZE_(VMD_DATA_SIZE(__VA_ARGS__), __VA_ARGS__)
PP_VA_SIZE(1, 2) // 2 PP_VA_SIZE(1) // 1 PP_VA_SIZE() // 0 :))
Thanks for this code. I will try to see if it works, and also try to test it on compilers other than gcc and VC++. If it does, I will incorporate it in order to return a size of 0 when the parameter list is empty if that is the correct thing to do. OTOH if it is illegal for variadic macros to take an empty parameter list, which seems to be the case, it would be better to see if I can generate an error, even if the compiler allows it.
The strange thing about this code is that `PP_VA_SIZE()` as well as `VMD_DATA_SIZE()` don't give an error in the first place. They should error because they are passed with an empty macro parameter (which is not legal). It would have been legal instead to pass a parameter expanding to empty like in `PP_VA_SIZE(BOOST_PP_EMPTY())` or `VMD_DATA_SIZE(BOOST_PP_EMPTY())`.
Why `PP_VA_SIZE()` and `VMD_DATA_SIZE()` accept empty macro parameter? Is that a variadic macros' feature or a MSVC bug?
I am not sure if it is a compiler bug or not. I will look at the problem and see what I can do. BTW there has already been an updated version of the variadic_macro_data library in the sandbox now ( version 1.3 ) which changes no functionality but which follows Boost naming conventions ( and also conveniently shortens the name of the header file to vmd.hpp ).
From http://www.open-std.org/JTC1/SC22/WG14/www/docs/C99RationaleV5.10.pdf There must be at least one argument to match the ellipsis. This requirement avoids the problems that occur when the trailing arguments are included in a list of arguments to another macro or function. For example, if dprintf had been defined as 10 #define dprintf(format, ...) \ dfprintf(stderr, format, _ _VA_ARGS_ _) and it were allowed for there to be only one argument, then there would be a trailing comma in the expanded form. While some implementations have used various notations or conventions to work around this problem, the Committee felt it better to avoid the problem altogether. 15 Similarly, the _ _VA_ARGS_ _ notation was preferred to other proposals for this syntax. A new feature of C99: Function-like macro invocations may also now have empty arguments, that is, an argument may consist of no preprocessing tokens. In C89, any argument that consisted of no preprocessing tokens had undefined behavior, but was noted as a common extension. 20 A function-like macro invocation f() has the form of either a call with no arguments or a call with one empty argument. Which form it actually takes is determined by the definition of f, which indicates the expected number of arguments.
BTW, a few minor comments on you library: 1) I think a name like BOOST_PP_VA_... is better than BOOST_VMD. "VA" is the same abbreviation for variadics that C99 uses in __VA_ARGS__ and Boost.Preprocessor already uses abbreviations like in BOOST_PP_SEQ.
What does the BOOST_PP_SEQ abbreviation have to do with BOOST_VMD_ ?
I was pointing out hat Boost.Preprocessor already uses some abbreviation so "VARIADICS" doesn't necessarily need to be spelled out completely.
OK, understood. I try to keep the names short in my libraries if I can.
Alternatively, I would consider BOOST_PP_VARIADICS_... but still not "VMD" because programmers will not know what VMD stands for.
I used VMD to represent (V)ariadic(M)acro(D)ata, which is really what my library is about and also integrating that data with Boost PP. I rejected VA because its connotation in C++ is "variable argument(s)" and my library is
I think __VA_ARGS__ stands for VAriadics ARGumentS so VA only abbreviates VAriadics. However, I couldn't find an actual standard reference that explicitly defines what the word __VA_ARGS__ stands for.
It is not that important. VMD expresses what I want, VA does not.
about manipulating variadic macro data. I feel that something like VARIADICS is too long but I would certainly agree to it if others found it more expressive. I also do not want it to be BOOST_PP_ anything unless others decide it should be part of Boost PP and not its own library, and in that case I feel Paul Mensonides would need to find that acceptable.
IMO, library users would expect your library to be part of Boost.Preprocessor. It's like adding another data set to Boost.Preprocessor for variadics.
I do not agree with this, although I understand the reasoning. I do not think one can just add to another library, even if one does something which in itself is an addition/extension to another library's implementation, without the other library programmer's approval. If it were decided that the VMD library were to become a part of Boost PP, and Paul Mensonides approved that, I would have no problem making it so.
2) I would add PP_VA_EAT, PP_VA_IDENTITY, PP_VA_CAT (similar to what they do already in Boost.Preprocessor and they should be trivial to implement). Also, I would add `#define PP_VA_SAME(...) __VA_ARGS__`.
I am willing to add functionality to the library but I wonder where that would stop. Essentially variadic macro data is similar to any of the other
I agree, no point in duplicating Boost.Preprocessor API. However, in using your library even just a bit I needed things like PP_VA_EAT, PP_VA_IDENTITY, PP_VA_CAT to program control statements like BOOST_PP_IIF, etc. While all of these are trivial to implement, it would be annoying to to re-implement all these facility macros all the times... It would be interesting to know what other programmer experience is in using your library to decide which Boost.Preprocessor control and facility macros are the most commonly used with variadics arguments.
I agree with that. I am of course willing to add some basic facilities. But I still think that you should think about converting variadic macro data to another functionally richer Boost PP data type first before you do anything else with the data.
data types in Boost PP in that it is really just a separate data type. Since the Boost PP data types already have a rich set of functionality I sort of feel that duplicating any of that functionality for variadic data itself will be redundant. This is especially true as my library has support for converting back and forth variadic data to any of the Boost PP data types. I feel pretty strongly that the use of variadic data with Boost PP should really be to provide a more pleasant syntax for the end-user, but once the programmer handles the variadic data he should convert it to a Boost PP data simply because that data type already has a rich set of functionality for dealing with the data.
I would be willing to add BOOST_VMD_CAT and BOOST_VMD_IDENTITY since they are both trivial ( just call to the appropiate BOOST_PP_ macros passing __VA_ARGS__ ). Your last is just __VA_ARGS__ as you show. But I really
I often do:
#define DO_(p) // do something wiht p... #define DO(cond, p) BOOST_PP_IIF(cond, DO_, p BOOST_PP_TUPLE_EAT(1))(p)
Convert variadic macro data to a Boost PP tuple with BOOST_VMD_DATA_TO_PP_TUPLE(...) and then you can manipulate the result as a tuple as above. Sure it is an extra step but, as I said previously, I think it is a mistake to try to duplicate any of the functionality of the much more functional Boost PP data types. Of course I can try to do it if people want to work with variadic data directly, but considering how much richer in functionality the Boost PP data types already are it just does not seem worthwhile to do, and would end up being a great deal of work for little actual purpose.
But I can't do this with variadic p because the IF will have too many arguments is p is __VA_ARGS__. So SAME() would be handy:
#define PP_VA_SAME(...) __VA_ARGS__ #define DO_(...) // do something with __VA_ARGS__... #define DO(cond, ...) BOOST_PP_IIF(cond, DO_, PP_VA_SAME)(__VA_ARGS__)
wonder if more functionality on variadic macro data is really worth it considering that the goal of the library, other than letting the end-user access individual tokens in the variadic macro data itself, is to convert back and forth to the Boost PP data types. I can understand that an end-user of the library such as yourself might want a number of additional operations on the variadic macro data itself, but I think if you look at the Boost PP data types you will see that their rich functionality offers most anything one would want to do with the data once you get it.