Hi all, I was just thinking (actually, I needed this, while doing some coding), that STATIC_ASSERT could get a little of the SMART_ASSERT flavour.
What am I talking about? In case a STATIC_ASSERT fails, how about dumping some data that was involved in the expression? Before you'll say it's already happening, I found myself wanting more. Consider the following trivial example: #include <boost/static_assert.hpp> #include <string> template< class type1, class type2> struct type1_bigger { type1_bigger() { BOOST_STATIC_ASSERT( sizeof(type1) > sizeof(type2) ); } }; class Test { std::string s; }; int main(int argc, char* argv[]) { // assertion failed type1_bigger< int, Test> i; return 0; } -------------------- Gcc3.2 says: main.cpp: In constructor `type1_bigger<type1, type2>::type1_bigger() [with type1 = int, type2 = Test]': main.cpp:15: instantiated from here main.cpp:7: `sizeof' applied to incomplete type ` boost::STATIC_ASSERTION_FAILURE<false>' VC6 says: : error C2027: use of undefined type 'STATIC_ASSERTION_FAILURE<0>' ...\static_assert_ext.cpp(11) : while compiling class-template member function '__thiscall type1_bigger<int,class Test>::type1_bigger<int,class Test>(void)' and Comeau says: "ComeauTest.c", line 24: error: incomplete type is not allowed instantiation of "type1_bigger<type1, type2>::type1_bigger() [with type1=int, type2=Test]" at line 73 ------------------- Now that's not much use for me, since I would like to know sizeof(Test), for instance. So, we can help the compiler in this direction: - let the compiler know what to output in case the assertion fails: types or values. Of course, types are usually outputted anyway, but still, just in case, depending on your tested expression you might need different types (to be outputted) as well. How to do this? Simple ;-) I've attached an example. You can also get it from www.torjo.com/code/static_assert.txt Compile with your favorite compiler, and see the generated compile-time errors (I have tested with VC6, gcc3.2 and comeau, but we can modify the code to work with a lot more compilers). What do you think? Best, John -- John Torjo -- "Practical C++" column writer for builder.com.com Freelancer, C++ consultant mailto:[EMAIL PROTECTED]
namespace boost { template <bool x> struct STATIC_ASSERTION_FAILURE_BASE; template <> struct STATIC_ASSERTION_FAILURE_BASE<true> { enum { value = 1 }; }; namespace static_assert { class not_used {}; } // in order we need to 'dump' constants template< int i> class const_value {}; template< bool x, class type1 = static_assert::not_used , class type2 = static_assert::not_used, class type3 = static_assert::not_used, class type4 = static_assert::not_used, class type5 = static_assert::not_used, class type6 = static_assert::not_used, class type7 = static_assert::not_used > struct STATIC_ASSERTION_FAILURE : public STATIC_ASSERTION_FAILURE_BASE< x> { }; template<int x> struct static_assert_test{}; } // namespace boost #define INT_(x) ::boost::const_value<(x)> // for MSVC #define BOOST_STATIC_ASSERT1( B, val1 ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ), val1 >)\ > boost_static_assert_typedef_ #define BOOST_STATIC_ASSERT2( B, val1, val2 ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ), val1, val2 >)\ > boost_static_assert_typedef_ #define BOOST_STATIC_ASSERT4( B, val1, val2, val3, val4 ) \ typedef ::boost::static_assert_test<\ sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ), val1, val2, val3, val4 >)\ > boost_static_assert_typedef_ //...etc /////////////////////////////////////////////// // Example template< class type1, class type2> struct type1_bigger { type1_bigger() { BOOST_STATIC_ASSERT4( sizeof(type1) > sizeof(type2), type1, type2, INT_(sizeof(type1)), INT_(sizeof(type2)) ); } }; int main(int argc, char* argv[]) { type1_bigger< int, char> i; // generated assertion failed type1_bigger< char, int> i2; return 0; }
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost