#include #include #include #include #include #include #include #include #include #include #define FALSE_PARAM(_, i, data) , \ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), i) && \ BOOST_PP_SEQ_ELEM(i, BOOST_PP_TUPLE_ELEM(2, 0, data)) #define ASSERT_INVALID_EXPR_IMPL(vars, num_vars, expr, msg, temp) \ struct temp { \ template \ static boost::mpl::false_ is_ok(int* \ BOOST_PP_REPEAT(num_vars, FALSE_PARAM, (vars, temp)), \ decltype(expr)* = 0); \ template \ static boost::mpl::true_ is_ok(bool, \ BOOST_PP_ENUM_BINARY_PARAMS(num_vars, temp, && BOOST_PP_INTERCEPT)); \ typedef decltype(is_ok((int*)0, BOOST_PP_SEQ_ENUM(vars))) test_type; \ }; \ static_assert(temp::test_type::value, msg); #define ASSERT_INVALID_EXPR(vars, expr, msg) \ ASSERT_INVALID_EXPR_IMPL(vars, BOOST_PP_SEQ_SIZE(vars), expr, msg, \ BOOST_PP_CAT(invalid_expr_test, __LINE__)) template struct A { T x; U y; ASSERT_INVALID_EXPR((x), x+y, "Can add x and y; bad"); }; int main() { A(); A(); // generates assertion failure }