From 8e1c68eefa4a54601acd59a8e1fd13f1b6c58b3e Mon Sep 17 00:00:00 2001 From: Lorenzo Caminiti Date: Tue, 13 Jan 2015 19:05:56 -0800 Subject: [PATCH] parsing exception specifications and virtual specifiers --- .../traits/aux_/keyword_paren.hpp | 31 +++++++-- .../ext_/preprocessor/traits/func.hpp | 26 ++++++- .../preprocessor/traits/func/aux_/index.hpp | 9 ++- .../ext_/preprocessor/traits/func/except.hpp | 68 +++++++++++++++++++ .../preprocessor/traits/func/verbatim.hpp | 8 +-- .../traits/func/virt_specifiers.hpp | 63 +++++++++++++++++ test/pp_func_traits/Jamfile.v2 | 2 + test/pp_func_traits/cv_qualifiers.cpp | 6 +- test/pp_func_traits/except.cpp | 40 +++++++++++ test/pp_func_traits/params.cpp | 8 +-- test/pp_func_traits/virt_specifiers.cpp | 47 +++++++++++++ 11 files changed, 290 insertions(+), 18 deletions(-) create mode 100644 include/boost/contract/ext_/preprocessor/traits/func/except.hpp create mode 100644 include/boost/contract/ext_/preprocessor/traits/func/virt_specifiers.hpp create mode 100644 test/pp_func_traits/except.cpp create mode 100644 test/pp_func_traits/virt_specifiers.cpp diff --git a/include/boost/contract/ext_/preprocessor/traits/aux_/keyword_paren.hpp b/include/boost/contract/ext_/preprocessor/traits/aux_/keyword_paren.hpp index 5566b53..c3e0194 100644 --- a/include/boost/contract/ext_/preprocessor/traits/aux_/keyword_paren.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/aux_/keyword_paren.hpp @@ -3,21 +3,43 @@ #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_HPP_ #include -#include #include +#include +#include +#include /* PRIVATE */ +#define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_FRONT_(tokens) \ + BOOST_PP_IIF(BOOST_CONTRACT_EXT_PP_HAS_PAREN(tokens), \ + BOOST_CONTRACT_EXT_PP_PAREN_FRONT \ + , \ + BOOST_PP_TUPLE_EAT(1) \ + )(tokens) + +// Precondition: tokens = `keyword ...` #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_( \ tokens, remove_keyword_macro) \ - BOOST_CONTRACT_EXT_PP_PAREN_FRONT(remove_keyword_macro(tokens)) + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_FRONT_( \ + remove_keyword_macro(tokens)) +#define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP_EAT_(tokens) \ + BOOST_PP_EXPR_IIF(BOOST_CONTRACT_EXT_PP_HAS_PAREN(tokens), \ + BOOST_PP_TUPLE_EAT(0) \ + ) \ + tokens + +// Precondition: tokens = `keyword ...` #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP_( \ tokens, remove_keyword_macro) \ - BOOST_PP_TUPLE_EAT(0) remove_keyword_macro(tokens) + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP_EAT_( \ + remove_keyword_macro(tokens)) /* PUBLIC */ - + +// If tokens = `keyword(,,,) ...` expand to `(,,,)`, otherwise (i.e., both no +// keyword `(,,,) ...` and keyword with no parenthesis `keyword ...`) expand to +// EMPTY(). #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN( \ tokens, is_keyword_macro, remove_keyword_macro) \ BOOST_PP_IIF(is_keyword_macro(tokens), \ @@ -26,6 +48,7 @@ BOOST_PP_TUPLE_EAT(2) \ )(tokens, remove_keyword_macro) +// Expand tokens = `keyword(,,,) ...` and `keyword ...` to `...`. #define BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP( \ tokens, is_keyword_macro, remove_keyword_macro) \ BOOST_PP_IIF(is_keyword_macro(tokens), \ diff --git a/include/boost/contract/ext_/preprocessor/traits/func.hpp b/include/boost/contract/ext_/preprocessor/traits/func.hpp index 64bc017..0ee8df0 100644 --- a/include/boost/contract/ext_/preprocessor/traits/func.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/func.hpp @@ -8,6 +8,8 @@ #ifndef BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_HPP_ #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_HPP_ +#include +#include #include #include #include @@ -26,6 +28,26 @@ // NOTE: These macros #definitions read TRITS_FUNC instead of FUNC_TRAITS to // avoid name clashes with macro #define in func/*. +#if defined(BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST) && \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST < \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_VIRT_SPECIFIERS_INDEX +# define BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_VIRT_SPECIFIERS_(sign_traits) \ + sign_traits +#else +# define BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_VIRT_SPECIFIERS_(sign_traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_PARSE(sign_traits) +#endif + +#if defined(BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST) && \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST < \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_EXCEPT_INDEX +# define BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_EXCEPT_(sign_traits) \ + sign_traits +#else +# define BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_EXCEPT_(sign_traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_PARSE(sign_traits) +#endif + #if defined(BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST) && \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_INDEX_TEST < \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_REF_INDEX @@ -143,6 +165,8 @@ // WARNING: Order of these macros must match ..._INDEX values (see index.hpp). #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS(sign) \ BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_DONE_( \ + BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_VIRT_SPECIFIERS_( \ + BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_EXCEPT_( \ BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_REF_( \ BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_CV_QUALIFIERS_( \ BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_PARAMS_( \ @@ -155,7 +179,7 @@ BOOST_CONTRACT_EXT_PP_TRAITS_FUNC_ACCESS_( \ BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_INIT( \ sign \ - )))))))))))) + )))))))))))))) #endif // #include guard diff --git a/include/boost/contract/ext_/preprocessor/traits/func/aux_/index.hpp b/include/boost/contract/ext_/preprocessor/traits/func/aux_/index.hpp index 2d2b9e7..4d9b845 100644 --- a/include/boost/contract/ext_/preprocessor/traits/func/aux_/index.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/func/aux_/index.hpp @@ -38,7 +38,14 @@ #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_REF_INDEX 17 -#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_DONE_INDEX 18 +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_EXCEPT_INDEX 18 + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_FINAL_INDEX 19 +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_OVERRIDE_INDEX 20 +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_VIRT_SPECIFIERS_INDEX \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_OVERRIDE_INDEX + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_DONE_INDEX 21 #endif // #include guard diff --git a/include/boost/contract/ext_/preprocessor/traits/func/except.hpp b/include/boost/contract/ext_/preprocessor/traits/func/except.hpp new file mode 100644 index 0000000..4ecc7fc --- /dev/null +++ b/include/boost/contract/ext_/preprocessor/traits/func/except.hpp @@ -0,0 +1,68 @@ + +#ifndef BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_HPP_ +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_HPP_ + +#include +#include +#include +#include +#include +#include +#include + +/* PRIVATE */ + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_( \ + sign, traits, keyword, is_keyword_macro, remove_keyword_macro) \ + ( \ + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP(sign, \ + is_keyword_macro, remove_keyword_macro) \ + , \ + BOOST_CONTRACT_EXT_PP_TRAITS_PUSH_BACK( \ + traits, \ + keyword \ + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN(sign, \ + is_keyword_macro, remove_keyword_macro) \ + BOOST_PP_EMPTY \ + ) \ + ) + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_NONE_(sign, traits) \ + (sign, BOOST_CONTRACT_EXT_PP_TRAITS_PUSH_BACK(traits, BOOST_PP_EMPTY)) + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_NOEXCEPT_(sign, traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_(sign, traits, \ + noexcept, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_IS_NOEXCEPT_FRONT, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_NOEXCEPT_REMOVE_FRONT \ + ) + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_THROW_(sign, traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_(sign, traits, \ + throw, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_IS_THROW_FRONT, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_THROW_REMOVE_FRONT \ + ) + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_PARSE_ARGS_(sign, traits) \ + BOOST_PP_IIF(BOOST_CONTRACT_EXT_PP_KEYWORD_IS_NOEXCEPT_FRONT(sign), \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_NOEXCEPT_ \ + , BOOST_PP_IIF(BOOST_CONTRACT_EXT_PP_KEYWORD_IS_THROW_FRONT(sign), \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_THROW_ \ + , \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_NONE_ \ + ))(sign, traits) + +/* PUBLIC */ + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_PARSE(sign_traits) \ + BOOST_CONTRACT_EXT_PP_EXPAND_ONCE( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT_PARSE_ARGS_ sign_traits) + +// Expand to `noexcept | noexcept(,,,) | throw(,,,) | EMPTY()`. +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT(traits) \ + BOOST_CONTRACT_EXT_PP_TRAITS_ELEM( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_EXCEPT_INDEX, traits)() + +#endif // #include guard + diff --git a/include/boost/contract/ext_/preprocessor/traits/func/verbatim.hpp b/include/boost/contract/ext_/preprocessor/traits/func/verbatim.hpp index 00b221a..e7bbcfa 100644 --- a/include/boost/contract/ext_/preprocessor/traits/func/verbatim.hpp +++ b/include/boost/contract/ext_/preprocessor/traits/func/verbatim.hpp @@ -8,7 +8,7 @@ #include #include -// PRIVATE // +/* PRIVATE */ #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VERBATIM_SIGN_(sign, traits) \ BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD_PAREN_SKIP( \ @@ -28,7 +28,7 @@ BOOST_PP_EMPTY \ ) -// PUBLIC // +/* PUBLIC */ #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VERBATIM_PARSE(sign_traits) \ ( \ @@ -40,9 +40,7 @@ // Expand to `(,,,) | EMPTY()`. #define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VERBATIM(traits) \ BOOST_CONTRACT_EXT_PP_TRAITS_ELEM( \ - BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_VERBATIM_INDEX, \ - traits \ - )() + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_VERBATIM_INDEX, traits)() #endif // #include guard diff --git a/include/boost/contract/ext_/preprocessor/traits/func/virt_specifiers.hpp b/include/boost/contract/ext_/preprocessor/traits/func/virt_specifiers.hpp new file mode 100644 index 0000000..94883cb --- /dev/null +++ b/include/boost/contract/ext_/preprocessor/traits/func/virt_specifiers.hpp @@ -0,0 +1,63 @@ + +#ifndef BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_HPP_ +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* PRIVATE */ + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_( \ + sign_virt, traits) \ + ( \ + BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_FIRST(sign_virt) \ + , \ + BOOST_CONTRACT_EXT_PP_TRAITS_PUSH_BACK( \ + BOOST_CONTRACT_EXT_PP_TRAITS_PUSH_BACK( \ + traits, \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(2, 0, \ + BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_SECOND(sign_virt)), \ + final \ + ) \ + BOOST_PP_EMPTY \ + ), \ + BOOST_PP_EXPR_IIF(BOOST_PP_TUPLE_ELEM(2, 1, \ + BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_SECOND(sign_virt)), \ + override \ + ) \ + BOOST_PP_EMPTY \ + ) \ + ) + +/* PUBLIC */ + +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_PARSE(sign_traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VIRT_SPECIFIERS_( \ + BOOST_CONTRACT_EXT_PP_TRAITS_AUX_KEYWORD2_COMB_PARSE( \ + BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_FIRST(sign_traits), \ + BOOST_CONTRACT_EXT_PP_KEYWORD_IS_FINAL_FRONT, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_FINAL_REMOVE_FRONT, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_IS_OVERRIDE_FRONT, \ + BOOST_CONTRACT_EXT_PP_KEYWORD_OVERRIDE_REMOVE_FRONT \ + ), \ + BOOST_CONTRACT_EXT_PP_SIGN_TRAITS_SECOND(sign_traits) \ + ) + +// Expand to `final | EMPTY()`. +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_FINAL(traits) \ + BOOST_CONTRACT_EXT_PP_TRAITS_ELEM( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_FINAL_INDEX, traits)() + +// Expand to `override | EMPTY()`. +#define BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_OVERRIDE(traits) \ + BOOST_CONTRACT_EXT_PP_TRAITS_ELEM( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_AUX_OVERRIDE_INDEX, traits)() + +#endif // #include guard + diff --git a/test/pp_func_traits/Jamfile.v2 b/test/pp_func_traits/Jamfile.v2 index b82afc2..3abfe13 100644 --- a/test/pp_func_traits/Jamfile.v2 +++ b/test/pp_func_traits/Jamfile.v2 @@ -24,6 +24,8 @@ test-pp name ; test-pp params ; test-pp cv_qualifiers ; test-pp ref ; +test-pp except ; +test-pp virt_specifiers ; # TODO: Try to automatically run and test wave too... Maybe something like this: # SHELL "wave access.cpp" ; diff --git a/test/pp_func_traits/cv_qualifiers.cpp b/test/pp_func_traits/cv_qualifiers.cpp index 5e48136..2dbd98b 100644 --- a/test/pp_func_traits/cv_qualifiers.cpp +++ b/test/pp_func_traits/cv_qualifiers.cpp @@ -18,7 +18,7 @@ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_CONST(func_traits) \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_VOLATILE(func_traits) -#define BOOST_CONTRACT_TEST_PARSED_(trait, parsed) \ +#define BOOST_CONTRACT_TEST_EQUAL_(trait, parsed) \ BOOST_CONTRACT_TEST_AUX_PP_TRAITS( \ BOOST_CONTRACT_TEST_CV_QUALIFIERS_, \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS, \ @@ -29,7 +29,7 @@ ) #define BOOST_CONTRACT_TEST_(trait) \ - BOOST_CONTRACT_TEST_PARSED_(trait, trait) + BOOST_CONTRACT_TEST_EQUAL_(trait, trait) int main ( ) { BOOST_CONTRACT_TEST_( BOOST_PP_EMPTY() ) @@ -37,7 +37,7 @@ int main ( ) { BOOST_CONTRACT_TEST_( volatile ) BOOST_CONTRACT_TEST_( const volatile ) // Same as `const volatile` once parsed (this order does not matter in C++). - BOOST_CONTRACT_TEST_PARSED_( volatile const, const volatile ) + BOOST_CONTRACT_TEST_EQUAL_( volatile const, const volatile ) return BOOST_CONTRACT_TEST_AUX_PP_TRAITS_REPORT_ERRORS; } diff --git a/test/pp_func_traits/except.cpp b/test/pp_func_traits/except.cpp new file mode 100644 index 0000000..99f626e --- /dev/null +++ b/test/pp_func_traits/except.cpp @@ -0,0 +1,40 @@ + +#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_EXCEPT_INDEX + +#include "../aux_/pp_traits.hpp" +#include +#include + +#define BOOST_CONTRACT_TEST_(trait) \ + BOOST_CONTRACT_TEST_AUX_PP_TRAITS( \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_EXCEPT, \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS, \ + (std::map&) (f) ( int x, (std::map&) y ) const, \ + trait, \ + final override, \ + trait \ + ) + +int main ( ) { + BOOST_CONTRACT_TEST_( BOOST_PP_EMPTY() ) + + BOOST_CONTRACT_TEST_( noexcept ) + BOOST_CONTRACT_TEST_( noexcept(sizeof(int) < 16) ) + BOOST_CONTRACT_TEST_( noexcept(my::map::key_size) ) + + BOOST_CONTRACT_TEST_( throw() ) + BOOST_CONTRACT_TEST_( throw(std::exception) ) + BOOST_CONTRACT_TEST_( throw(std::exception, my::map::error) ) + + return BOOST_CONTRACT_TEST_AUX_PP_TRAITS_REPORT_ERRORS; +} + +#endif // variadics + diff --git a/test/pp_func_traits/params.cpp b/test/pp_func_traits/params.cpp index e58175b..979d3b1 100644 --- a/test/pp_func_traits/params.cpp +++ b/test/pp_func_traits/params.cpp @@ -56,7 +56,7 @@ ) // Variadic to allow to specify empty params `( )`. -#define BOOST_CONTRACT_TEST_PARSED_(params_sign, parsed_params) \ +#define BOOST_CONTRACT_TEST_EQUAL_(params_sign, parsed_params) \ BOOST_CONTRACT_TEST_AUX_PP_TRAITS( \ BOOST_CONTRACT_TEST_PARAMS_, \ BOOST_CONTRACT_EXT_PP_FUNC_TRAITS, \ @@ -67,12 +67,12 @@ ) #define BOOST_CONTRACT_TEST_(...) \ - BOOST_CONTRACT_TEST_PARSED_( (__VA_ARGS__), (__VA_ARGS__) ) + BOOST_CONTRACT_TEST_EQUAL_( (__VA_ARGS__), (__VA_ARGS__) ) int main ( ) { // Test empty and void. BOOST_CONTRACT_TEST_( ) - BOOST_CONTRACT_TEST_PARSED_( ( void ), ( ) ) + BOOST_CONTRACT_TEST_EQUAL_( ( void ), ( ) ) // Test named. BOOST_CONTRACT_TEST_( int x ) @@ -112,7 +112,7 @@ int main ( ) { ) // Test variadics. - BOOST_CONTRACT_TEST_PARSED_( ( int count, (...) ), ( int count, ... ) ) + BOOST_CONTRACT_TEST_EQUAL_( ( int count, (...) ), ( int count, ... ) ) return BOOST_CONTRACT_TEST_AUX_PP_TRAITS_REPORT_ERRORS; } diff --git a/test/pp_func_traits/virt_specifiers.cpp b/test/pp_func_traits/virt_specifiers.cpp new file mode 100644 index 0000000..9234a5b --- /dev/null +++ b/test/pp_func_traits/virt_specifiers.cpp @@ -0,0 +1,47 @@ + +#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_VIRT_SPECIFIERS_INDEX + +#include "../aux_/pp_traits.hpp" +#include +#include + +#include + +#define BOOST_CONTRACT_TEST_VIRT_SPECIFIERS_(func_traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_FINAL(func_traits) \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS_OVERRIDE(func_traits) + +#define BOOST_CONTRACT_TEST_EQUAL_(trait, parsed) \ + BOOST_CONTRACT_TEST_AUX_PP_TRAITS( \ + BOOST_CONTRACT_TEST_VIRT_SPECIFIERS_, \ + BOOST_CONTRACT_EXT_PP_FUNC_TRAITS, \ + (std::map&) (f) ( int x, (std::map&) y ) \ + throw(int, double), \ + trait, \ + precondition(x > 0) postcondition(x == 0 ? y.empty() : true), \ + parsed \ + ) + +#define BOOST_CONTRACT_TEST_(trait) \ + BOOST_CONTRACT_TEST_EQUAL_(trait, trait) + +int main ( ) { + BOOST_CONTRACT_TEST_( BOOST_PP_EMPTY() ) + BOOST_CONTRACT_TEST_( final ) + BOOST_CONTRACT_TEST_( override ) + BOOST_CONTRACT_TEST_( final override ) + // Same as `const volatile` once parsed (this order does not matter in C++). + BOOST_CONTRACT_TEST_EQUAL_( override final, final override ) + + return BOOST_CONTRACT_TEST_AUX_PP_TRAITS_REPORT_ERRORS; +} + +#endif // variadics +