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

Reply via email to