From 50137de90ce522df0145acccf0b615df7eaa4773 Mon Sep 17 00:00:00 2001 From: Lorenzo Caminiti Date: Wed, 31 Dec 2014 03:02:43 -0800 Subject: [PATCH] pp parsing for func return --- Jamroot | 3 - .../generate.py => keyword-generate.py} | 9 ++- .../contract/ext_/preprocessor/paren/has.hpp | 4 +- .../ext_/preprocessor/traits/aux_/type.hpp | 5 +- .../ext_/preprocessor/traits/func/return.hpp | 4 +- test/pp_func_traits/Jamfile.v2 | 27 +++++-- test/pp_func_traits/return_.cpp | 76 +++++++++++++++++++ 7 files changed, 111 insertions(+), 17 deletions(-) rename include/boost/contract/ext_/preprocessor/{keyword/generate.py => keyword-generate.py} (95%) mode change 100755 => 100644 include/boost/contract/ext_/preprocessor/traits/func/return.hpp create mode 100644 test/pp_func_traits/return_.cpp diff --git a/Jamroot b/Jamroot index 6a2fc5a..1900fe5 100644 --- a/Jamroot +++ b/Jamroot @@ -22,9 +22,6 @@ project echo """ Examples: $ wave # pre-process to pp.* - - $ b2 -n # find compiler command then cut-n-paste it adding pp only option - $ -E -P -DDEBUG > pp.cpp """ ; diff --git a/include/boost/contract/ext_/preprocessor/keyword/generate.py b/include/boost/contract/ext_/preprocessor/keyword-generate.py similarity index 95% rename from include/boost/contract/ext_/preprocessor/keyword/generate.py rename to include/boost/contract/ext_/preprocessor/keyword-generate.py index ff327ab..980aaa9 100644 --- a/include/boost/contract/ext_/preprocessor/keyword/generate.py +++ b/include/boost/contract/ext_/preprocessor/keyword-generate.py @@ -1,5 +1,5 @@ -# Copyright (C) 2008-2012 Lorenzo Caminiti +# Copyright (C) 2008-2015 Lorenzo Caminiti # Distributed under the Boost Software License, Version 1.0 # (see accompanying file LICENSE_1_0.txt or a copy at # http://www.boost.org/LICENSE_1_0.txt) @@ -113,10 +113,11 @@ entries = [ ] script = os.path.basename(sys.argv[0]) +root = sys.argv[0].replace('-generate.py', '', 1) for entry in entries: - directory = entry['directory'] - keywords = entry['keywords'] + directory = os.path.join(root, entry['directory']) if not os.path.exists(directory): os.makedirs(directory) + keywords = entry['keywords'] for keyword in keywords: filename = keyword + ".hpp" path = os.path.join(directory, filename) @@ -128,7 +129,7 @@ for entry in entries: #define BOOST_CONTRACT_EXT_PP_KEYWORD_{1}_HPP_ // WARNING: FILE AUTOMATICALLY GENERATED, DO NOT MODIFY IT! -// Instead, modify and run the related generation script "{0}". +// Instead, modify and run related generation script "{0}". #include #include diff --git a/include/boost/contract/ext_/preprocessor/paren/has.hpp b/include/boost/contract/ext_/preprocessor/paren/has.hpp index e007c32..b562433 100644 --- a/include/boost/contract/ext_/preprocessor/paren/has.hpp +++ b/include/boost/contract/ext_/preprocessor/paren/has.hpp @@ -10,7 +10,7 @@ #include -// PRIVATE // +/* PRIVATE */ // Variadic so handle any arity. #define BOOST_CONTRACT_EXT_PP_HAS_PAREN_CHECK(...) \ @@ -19,7 +19,7 @@ #define BOOST_PP_CHECK_RESULT_BOOST_CONTRACT_EXT_PP_HAS_PAREN_CHECK \ 0, BOOST_PP_NIL -// PUBLIC // +/* PUBLIC */ // Adapted from BOOST_PP_IS_UNARY but for variadic macros. #define BOOST_CONTRACT_EXT_PP_HAS_PAREN(tokens) \ diff --git a/include/boost/contract/ext_/preprocessor/traits/aux_/type.hpp b/include/boost/contract/ext_/preprocessor/traits/aux_/type.hpp index 6b2f0cf..217ddb8 100644 --- a/include/boost/contract/ext_/preprocessor/traits/aux_/type.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/aux_/type.hpp @@ -2,6 +2,7 @@ #ifndef BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_HPP_ #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_HPP_ +#include #include #include #include @@ -23,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -182,7 +183,7 @@ #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_PARSE(tokens) \ BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_PARSE_D(1, tokens) -// TOOD: Should all _SKIP macros be removed and replaced by PARASE macros +// TODO: Should all _SKIP macros be removed and replaced by PARASE macros // that work on both sign and traits at the same time for efficiency and // consistency? diff --git a/include/boost/contract/ext_/preprocessor/traits/func/return.hpp b/include/boost/contract/ext_/preprocessor/traits/func/return.hpp old mode 100755 new mode 100644 index 7ad7179..6161830 --- a/include/boost/contract/ext_/preprocessor/traits/func/return.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/func/return.hpp @@ -48,7 +48,7 @@ #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_RETURN_YES_(sign, traits) \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_RETURN_TYPE_(traits, \ - BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_PRASE(sign)) + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_TYPE_PARSE(sign)) #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_RETURN_NO_(sign, traits) \ (sign, BOOST_CONTRACT_EXT_PP_TRAITS_PUSH_BACK(traits, BOOST_PP_EMPTY)) @@ -69,6 +69,8 @@ // Expand to `result_type | void | auto | EMPTY()` (auto for unified function // syntax in which case for the result type trait use `..._UNIFIED_RETURN`). #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_RETURN(traits) \ + BOOST_CONTRACT_EXT_PP_TRAITS_ELEM( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_RETURN_INDEX, traits)() #endif // #include guard diff --git a/test/pp_func_traits/Jamfile.v2 b/test/pp_func_traits/Jamfile.v2 index eb3d0ba..5d7cfaa 100644 --- a/test/pp_func_traits/Jamfile.v2 +++ b/test/pp_func_traits/Jamfile.v2 @@ -1,9 +1,26 @@ import testing ; -run access.cpp ; -run verbatim.cpp ; -run export.cpp ; -run template.cpp ; -run classifiers.cpp ; +echo "Examples: + b2 + compile and run test program .cpp + b2 -pp [cxxflags=-UDEBUG] + stop after preprocessing .cpp +""" ; + +rule test-pp ( filename ) { + run $(filename).cpp ; + preprocessed $(filename)-pp : $(filename).cpp : -DDEBUG ; + explicit filename-pp ; +} + +test-pp access ; +test-pp verbatim ; +test-pp export ; +test-pp template ; +test-pp classifiers ; +test-pp return_ ; + +# TODO: Try to automatically run and test wave too... +# SHELL "wave access.cpp" ; diff --git a/test/pp_func_traits/return_.cpp b/test/pp_func_traits/return_.cpp new file mode 100644 index 0000000..329a43f --- /dev/null +++ b/test/pp_func_traits/return_.cpp @@ -0,0 +1,76 @@ + +#include +#if !BOOST_PP_VARIADICS +# error "this compiler does not support variadic macros" +#else + +#include +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_RETURN_INDEX + +#include "../aux_/pp_traits.hpp" +#include +#include +#include +#include +#include +#include +#include + +// Wrap with parenthesis (if not empty and does not have parenthesis already). +#define BOOST_CONTRACT_TEST_PARENTHESIZE_(...) \ + BOOST_PP_IIF(BOOST_CONTRACT_EXT_PP_IS_EMPTY(__VA_ARGS__), \ + BOOST_PP_TUPLE_EAT(1) \ + , BOOST_PP_IIF(BOOST_CONTRACT_EXT_PP_HAS_PAREN(__VA_ARGS__ \ + BOOST_PP_EMPTY()), \ + BOOST_PP_TUPLE_REM(1) \ + , \ + BOOST_PP_EMPTY() \ + ))(__VA_ARGS__) + +#define BOOST_CONTRACT_TEST_(before, trait, after) \ + BOOST_CONTRACT_TEST_AUX_PP_TRAITS( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_RETURN, \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS, \ + before, \ + trait, \ + after, \ + BOOST_CONTRACT_TEST_PARENTHESIZE_(trait) \ + ) + +int main ( ) { + // Return (without and with parenthesis). + BOOST_CONTRACT_TEST_( + BOOST_PP_EMPTY(), + void, (f) ( ) + ) + BOOST_CONTRACT_TEST_( + BOOST_PP_EMPTY(), + (std::map), (f) ( ) + ) + + // No return (constructors, type-conversion operators, etc.). + BOOST_CONTRACT_TEST_( + BOOST_PP_EMPTY(), + BOOST_PP_EMPTY(), (ctor) ( int x ) + ) + BOOST_CONTRACT_TEST_( + BOOST_PP_EMPTY(), + BOOST_PP_EMPTY(), operator int ( ) + ) + BOOST_CONTRACT_TEST_( + BOOST_PP_EMPTY(), + BOOST_PP_EMPTY(), operator(int*)(int_ptr) ( ) + ) + + // Unified syntax return. + BOOST_CONTRACT_TEST_( + template( typename L, typename R ), + auto, (add) ( (L) left, (R) right ) return decltype(left + right) + ) + + return BOOST_CONTRACT_TEST_AUX_PP_TRAITS_REPORT_ERRORS; +} + +#endif // variadics +