00001 00004 #ifndef GMTL_STATIC_ASSERT_HPP 00005 #define GMTL_STATIC_ASSERT_HPP 00006 00007 #include <gmtl/Defines.h> 00008 #include <gmtl/Util/Meta.h> 00009 00010 #ifdef __BORLANDC__ 00011 // 00012 // workaround for buggy integral-constant expression support: 00013 #define GMTL_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS 00014 #endif 00015 00016 namespace gmtl 00017 { 00018 00019 // HP aCC cannot deal with missing names for template value parameters 00020 template <bool x> struct STATIC_ASSERTION_FAILURE; 00021 00022 template <> struct STATIC_ASSERTION_FAILURE<true>{}; 00023 00024 // HP aCC cannot deal with missing names for template value parameters 00025 template<int x> struct static_assert_test{}; 00026 00027 } 00028 00029 // 00030 // Implicit instantiation requires that all member declarations be 00031 // instantiated, but that the definitions are *not* instantiated. 00032 // 00033 // It's not particularly clear how this applies to enum's or typedefs; 00034 // both are described as declarations [7.1.3] and [7.2] in the standard, 00035 // however some compilers use "delayed evaluation" of one or more of 00036 // these when implicitly instantiating templates. We use typedef declarations 00037 // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum 00038 // version gets better results from your compiler... 00039 // 00040 // Implementation: 00041 // Both of these versions rely on sizeof(incomplete_type) generating an error 00042 // message containing the name of the incomplete type. We use 00043 // "STATIC_ASSERTION_FAILURE" as the type name here to generate 00044 // an eye catching error message. The result of the sizeof expression is either 00045 // used as an enum initialiser, or as a template argument depending which version 00046 // is in use... 00047 // Note that the argument to the assert is explicitly cast to bool using old- 00048 // style casts: too many compilers currently have problems with static_cast 00049 // when used inside integral constant expressions. 00050 // 00051 #if !defined(GMTL_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) && !defined(__MWERKS__) 00052 #ifndef GMTL_MSVC 00053 #define GMTL_STATIC_ASSERT( B ) \ 00054 typedef ::gmtl::static_assert_test<\ 00055 sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ 00056 GMTL_JOIN(gmtl_static_assert_typedef_, __LINE__) 00057 #else 00058 // __LINE__ macro broken when -ZI is used see Q199057 00059 // fortunately MSVC ignores duplicate typedef's. 00060 #define GMTL_STATIC_ASSERT( B ) \ 00061 typedef ::gmtl::static_assert_test<\ 00062 sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >)\ 00063 > gmtl_static_assert_typedef_ 00064 #endif 00065 #else 00066 // alternative enum based implementation: 00067 #define GMTL_STATIC_ASSERT( B ) \ 00068 enum { GMTL_JOIN(gmtl_static_assert_enum_, __LINE__) \ 00069 = sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } 00070 #endif 00071 00072 00073 #endif // GMTL_STATIC_ASSERT_HPP