
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
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 :))
This does not work under gcc or msvc: #include <boost/variadic_macro_data/vmd.hpp> #include <boost/preprocessor.hpp> #include <boost/preprocessor/facilities/is_empty.hpp> #if !defined(BOOST_NO_VARIADIC_MACROS) #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__) #endif int main() { int j = PP_VA_SIZE(2); return 0; } gcc: "...patience... ...found 319 targets... ...updating 4 targets... gcc.compile.c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o test_data_try.cpp: In function 'int main()': test_data_try.cpp:23:11: error: 'BOOST_PP_IIF_BOOST_PP_COMPL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_VMD_DATA_SIZE' was not declared in this scope test_data_try.cpp:23:1: error: 'BOOST_PP_NOT_EQUAL_1' was not declared in this scope test_data_try.cpp:12:9: error: 'PP_VA_SIZE_1OR0_' was not declared in this scope test_data_try.cpp:23:11: error: 'VMD_DATA_SIZE' was not declared in this scope test_data_try.cpp:23:11: error: expected ')' before 'BOOST_PP_EMPTY' test_data_try.cpp:23:7: warning: unused variable 'j' "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -pedantic -g -Wno-variadic-macros -I"..\..\.." -I"C:\Programming\VersionControl\boost" -c -o "..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o" "test_data_try.cpp" ...failed gcc.compile.c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o... msvc: "...patience... ...found 331 targets... ...updating 5 targets... compile-c-c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj test_data_try.cpp test_data_try.cpp(23) : error C2065: 'BOOST_PP_NOT_EQUAL_1' : undeclared identifier test_data_try.cpp(23) : error C2065: 'PP_VA_SIZE_1OR0_' : undeclared identifier test_data_try.cpp(23) : error C2146: syntax error : missing ')' before identifier 'PP_VA_EAT' test_data_try.cpp(23) : error C3861: 'BOOST_PP_IIF_BOOST_PP_COMPL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_VMD_DATA_SIZE': identifier not found test_data_try.cpp(23) : error C3861: 'VMD_DATA_SIZE': identifier not found test_data_try.cpp(23) : error C2059: syntax error : ')' call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 >nul cl /Zm800 -nologo @"..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj.rsp" ...failed compile-c-c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj... My own best try at a CHECK_EMPTY macro so far is: #include <boost/variadic_macro_data/vmd.hpp> #include <boost/preprocessor.hpp> #if !defined(BOOST_NO_VARIADIC_MACROS) #define CAT_ONE(...) VMD_DETAIL_CAT(1,__VA_ARGS__) #define CHECK_EMPTY(...) \ BOOST_PP_IIF \ ( \ BOOST_PP_EQUAL(1,BOOST_VMD_DATA_SIZE(CAT_ONE(__VA_ARGS__))), \ BOOST_PP_EQUAL(1,BOOST_VMD_DATA_ELEM(0,CAT_ONE(__VA_ARGS__))), \ 0 \ ) \ /**/ #endif int main() { int i = CHECK_EMPTY(); int j = CHECK_EMPTY(1); int k = CHECK_EMPTY(a,b,c); // int m = CHECK_EMPTY(a); return 0; } The idea is to paste '1' the front of the variadic macro data sequence and if there is just '1' as the size and the token is '1', the sequence must have been empty to begin with. This works correctly returning 1 for i and a 0 for j or k until I uncomment the 'int m' line. Evidently one can not do BOOST_PP_EQUAL if one of the parameters is not a number. I get on msvc: ...patience... ...found 329 targets... ...updating 5 targets... compile-c-c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj test_data_try.cpp test_data_try.cpp(24) : error C2065: 'BOOST_PP_NIL' : undeclared identifier test_data_try.cpp(24) : error C3861: 'BOOST_PP_COMPL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_1a': identifier not found call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 >nul cl /Zm800 -nologo @"..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj.rsp" ...failed compile-c-c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\msvc-10.0\debug\threading-multi\test_data_try.obj... and on gcc: ...patience... ...found 317 targets... ...updating 4 targets... gcc.compile.c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o test_data_try.cpp:21:23: warning: invoking macro CHECK_EMPTY argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:23: warning: invoking macro CHECK_EMPTY argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:23: warning: invoking macro CAT_ONE argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:23: warning: invoking macro VMD_DETAIL_CAT argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:23: warning: invoking macro VMD_DETAIL_PRIMITIVE_CAT argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:1: warning: invoking macro CAT_ONE argument 1: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:1: warning: invoking macro VMD_DETAIL_CAT argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp:21:1: warning: invoking macro VMD_DETAIL_PRIMITIVE_CAT argument 2: empty macro arguments are undefined in ISO C90 and ISO C++98 test_data_try.cpp: In function 'int main()': test_data_try.cpp:24:1: error: 'BOOST_PP_NIL' was not declared in this scope test_data_try.cpp:24:1: error: 'BOOST_PP_COMPL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_1a' was not declared in this scope test_data_try.cpp:21:7: warning: unused variable 'i' test_data_try.cpp:22:7: warning: unused variable 'j' test_data_try.cpp:23:7: warning: unused variable 'k' test_data_try.cpp:24:7: warning: unused variable 'l' "g++" -ftemplate-depth-128 -O0 -fno-inline -Wall -pedantic -g -Wno-variadic-macros -I"..\..\.." -I"C:\Programming\VersionControl\boost" -c -o "..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o" "test_data_try.cpp" ...failed gcc.compile.c++ ..\..\..\bin.v2\libs\variadic_macro_data\test\test_data_try.test\gcc-mingw-4.5.2\debug\test_data_try.o..." I think Paul Mensonides may be right and there is no foolproof way to check for a completely empty parameter list even using variadic macros. Further ideas ?