From e476f10f529e100e0a99844723c6d1b1fbc89824 Mon Sep 17 00:00:00 2001 From: Edward Diener Date: Wed, 25 Sep 2019 06:29:04 -0400 Subject: [PATCH] Added OPT macro to determine whether C++20's __VA_OPT__ is supported or not. Updated the undocumented variadic IS_EMPTY to use the functionality of __VA_OPT__ if it exists to provide perfect functionality for testing for emptiness. --- .../facilities/is_empty_variadic.hpp | 15 +++++++++ .../preprocessor/variadic/detail/opt.hpp | 30 +++++++++++++++++ include/boost/preprocessor/variadic/opt.hpp | 28 ++++++++++++++++ test/clang_cuda.cu | 5 +-- test/config_info.cpp | 3 ++ test/isempty.cxx | 15 ++++++++- test/isempty_variadic_standard_failure.cxx | 10 ++++++ test/isempty_variadic_standard_failure2.cxx | 10 ++++++ test/test.h | 21 ++---------- test/test_macro.h | 22 +++++++++++++ test/test_main.h | 32 +++++++++++++++++++ 11 files changed, 167 insertions(+), 24 deletions(-) create mode 100644 include/boost/preprocessor/variadic/detail/opt.hpp create mode 100644 include/boost/preprocessor/variadic/opt.hpp create mode 100644 test/test_macro.h create mode 100644 test/test_main.h diff --git a/include/boost/preprocessor/facilities/is_empty_variadic.hpp b/include/boost/preprocessor/facilities/is_empty_variadic.hpp index eee4062..403e74b 100644 --- a/include/boost/preprocessor/facilities/is_empty_variadic.hpp +++ b/include/boost/preprocessor/facilities/is_empty_variadic.hpp @@ -16,6 +16,20 @@ # # if BOOST_PP_VARIADICS # +# include +# +# if BOOST_PP_VARIADIC_OPT() +# +#define BOOST_PP_IS_EMPTY_FUNCTION2(...) \ + __VA_OPT__(0,) 1 \ +/**/ +#define BOOST_PP_IS_EMPTY_FUNCTION(...) \ + BOOST_PP_IS_EMPTY_FUNCTION2(__VA_ARGS__) \ +/**/ +#define BOOST_PP_IS_EMPTY(...) \ + BOOST_PP_VARIADIC_OPT_ELEM0(BOOST_PP_IS_EMPTY_FUNCTION(__VA_ARGS__),) \ +/**/ +# else # include # include # @@ -53,5 +67,6 @@ /**/ #define BOOST_PP_IS_EMPTY_ZERO(...) 0 # endif /* BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400 */ +# endif /* BOOST_PP_VARIADIC_OPT() */ # endif /* BOOST_PP_VARIADICS */ # endif /* BOOST_PREPROCESSOR_FACILITIES_IS_EMPTY_VARIADIC_HPP */ diff --git a/include/boost/preprocessor/variadic/detail/opt.hpp b/include/boost/preprocessor/variadic/detail/opt.hpp new file mode 100644 index 0000000..3b50850 --- /dev/null +++ b/include/boost/preprocessor/variadic/detail/opt.hpp @@ -0,0 +1,30 @@ +# /* ************************************************************************** +# * * +# * (C) Copyright Edward Diener 2019. * +# * Distributed under the Boost Software License, Version 1.0. (See * +# * accompanying file LICENSE_1_0.txt or copy at * +# * http://www.boost.org/LICENSE_1_0.txt) * +# * * +# ************************************************************************** */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_PREPROCESSOR_VARIADIC_DETAIL_OPT_HPP +# define BOOST_PREPROCESSOR_VARIADIC_DETAIL_OPT_HPP +# +# include +# +# if BOOST_PP_VARIADICS && defined(__cplusplus) && __cplusplus > 201703L +# +# define BOOST_PP_VARIADIC_OPT_FUNCTION(...) \ + __VA_OPT__(0,) 0, 0, 1 \ +/**/ +# +# define BOOST_PP_VARIADIC_OPT_ELEM0(e0, ...) BOOST_PP_VARIADIC_OPT_ELEM_0(e0,__VA_ARGS__) +# define BOOST_PP_VARIADIC_OPT_ELEM2(e0, ...) BOOST_PP_VARIADIC_OPT_ELEM_2(e0,__VA_ARGS__) +# define BOOST_PP_VARIADIC_OPT_ELEM_0(e0, ...) e0 +# define BOOST_PP_VARIADIC_OPT_ELEM_2(e0, e1, e2, ...) e2 +# +# endif +# +# endif diff --git a/include/boost/preprocessor/variadic/opt.hpp b/include/boost/preprocessor/variadic/opt.hpp new file mode 100644 index 0000000..c26b0d8 --- /dev/null +++ b/include/boost/preprocessor/variadic/opt.hpp @@ -0,0 +1,28 @@ +# /* ************************************************************************** +# * * +# * (C) Copyright Edward Diener 2019. * +# * Distributed under the Boost Software License, Version 1.0. (See * +# * accompanying file LICENSE_1_0.txt or copy at * +# * http://www.boost.org/LICENSE_1_0.txt) * +# * * +# ************************************************************************** */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_PREPROCESSOR_VARIADIC_OPT_HPP +# define BOOST_PREPROCESSOR_VARIADIC_OPT_HPP +# +# include +# +# /* BOOST_PP_VARIADIC_OPT */ +# +# if BOOST_PP_VARIADICS && defined(__cplusplus) && __cplusplus > 201703L +# include +# define BOOST_PP_VARIADIC_OPT() \ + BOOST_PP_VARIADIC_OPT_ELEM2(BOOST_PP_VARIADIC_OPT_FUNCTION(),) \ +/**/ +# else +# define BOOST_PP_VARIADIC_OPT() 0 +# endif +# +# endif diff --git a/test/clang_cuda.cu b/test/clang_cuda.cu index e2fd6d1..e13d656 100644 --- a/test/clang_cuda.cu +++ b/test/clang_cuda.cu @@ -9,10 +9,7 @@ # # /* See http://www.boost.org for most recent version. */ # -# include -# -# define BEGIN typedef int BOOST_PP_CAT(test_, __LINE__)[(( -# define END )==1) ? 1 : -1]; +# include #if defined(__clang__) && defined(__CUDACC__) && defined(__CUDA__) diff --git a/test/config_info.cpp b/test/config_info.cpp index cd80ba2..f800aa7 100644 --- a/test/config_info.cpp +++ b/test/config_info.cpp @@ -13,6 +13,7 @@ #include #include #include +#include static unsigned int indent = 4; static unsigned int width = 40; @@ -93,6 +94,8 @@ void print_macros() PRINT_MACRO(BOOST_PP_CONFIG_FLAGS()); PRINT_MACRO(BOOST_PP_VARIADICS); PRINT_MACRO(BOOST_PP_VARIADICS_MSVC); + PRINT_MACRO(BOOST_PP_VARIADICS_MSVC); + PRINT_MACRO(BOOST_PP_VARIADIC_OPT()); } int main() diff --git a/test/isempty.cxx b/test/isempty.cxx index 56bc81b..5fc8838 100644 --- a/test/isempty.cxx +++ b/test/isempty.cxx @@ -38,7 +38,20 @@ #if BOOST_PP_VARIADICS -#if BOOST_PP_VARIADICS_MSVC /* Testing the VC++ variadic version */ +# include + +#if defined(__cplusplus) && __cplusplus > 201703L && BOOST_PP_VARIADIC_OPT() + +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN2) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN3) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN4) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN5) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN8) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN9) == 0 END +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN10) == 0 END + +#elif BOOST_PP_VARIADICS_MSVC /* Testing the VC++ variadic version */ /* INCORRECT */ diff --git a/test/isempty_variadic_standard_failure.cxx b/test/isempty_variadic_standard_failure.cxx index feee25f..557014f 100644 --- a/test/isempty_variadic_standard_failure.cxx +++ b/test/isempty_variadic_standard_failure.cxx @@ -15,9 +15,19 @@ #if BOOST_PP_VARIADICS && (BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()) && !BOOST_PP_VARIADICS_MSVC #define FUNC_GEN8(x,y) (1,2,3) + +#if defined(__cplusplus) && __cplusplus > 201703L +# include + +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN8) == BOOST_PP_VARIADIC_OPT() END + +#else + BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN8) == 0 END +#endif + #else BEGIN 1 == 0 END diff --git a/test/isempty_variadic_standard_failure2.cxx b/test/isempty_variadic_standard_failure2.cxx index f51d497..c28bcd0 100644 --- a/test/isempty_variadic_standard_failure2.cxx +++ b/test/isempty_variadic_standard_failure2.cxx @@ -16,8 +16,18 @@ #define FUNC_GEN9(x,y,z) anything +#if defined(__cplusplus) && __cplusplus > 201703L + +# include + +BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN9) == BOOST_PP_VARIADIC_OPT() END + +#else + BEGIN BOOST_PP_IS_EMPTY(FUNC_GEN9) == 0 END +#endif + #else BEGIN 1 == 0 END diff --git a/test/test.h b/test/test.h index a5b37d6..d1d60c3 100644 --- a/test/test.h +++ b/test/test.h @@ -14,24 +14,7 @@ # ifndef BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_H # define BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_H # -# include +# include +# include # -# define BEGIN typedef int BOOST_PP_CAT(test_, __LINE__)[(( -# define END )==1) ? 1 : -1]; - -#if defined(__cplusplus) -#include -#if !defined(_STLP_MSVC) || _STLP_MSVC >= 1300 -namespace std { } -using namespace std; -#endif -#else -#include -#endif - -int main(void) { - printf("pass " __TIME__); - return 0; -} - # endif diff --git a/test/test_macro.h b/test/test_macro.h new file mode 100644 index 0000000..f9fe1f4 --- /dev/null +++ b/test/test_macro.h @@ -0,0 +1,22 @@ +# /* Copyright (C) 2001 +# * Housemarque Oy +# * http://www.housemarque.com +# * +# * Distributed under the Boost Software License, Version 1.0. (See +# * accompanying file LICENSE_1_0.txt or copy at +# * http://www.boost.org/LICENSE_1_0.txt) +# */ +# +# /* Revised by Paul Mensonides (2002) */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_MACRO_H +# define BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_MACRO_H +# +# include +# +# define BEGIN typedef int BOOST_PP_CAT(test_, __LINE__)[(( +# define END )==1) ? 1 : -1]; +# +# endif diff --git a/test/test_main.h b/test/test_main.h new file mode 100644 index 0000000..23797c2 --- /dev/null +++ b/test/test_main.h @@ -0,0 +1,32 @@ +# /* Copyright (C) 2001 +# * Housemarque Oy +# * http://www.housemarque.com +# * +# * Distributed under the Boost Software License, Version 1.0. (See +# * accompanying file LICENSE_1_0.txt or copy at +# * http://www.boost.org/LICENSE_1_0.txt) +# */ +# +# /* Revised by Paul Mensonides (2002) */ +# +# /* See http://www.boost.org for most recent version. */ +# +# ifndef BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_MAIN_H +# define BOOST_LIBS_PREPROCESSOR_REGRESSION_TEST_MAIN_H +# +#if defined(__cplusplus) +#include +#if !defined(_STLP_MSVC) || _STLP_MSVC >= 1300 +namespace std { } +using namespace std; +#endif +#else +#include +#endif + +int main(void) { + printf("pass " __TIME__); + return 0; +} + +# endif