00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum 00002 // Distributed under the GNU Lesser General Public License 2.1 with an 00003 // addendum covering inlined code. (See accompanying files LICENSE and 00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt) 00005 00009 #ifndef GMTL_STATIC_ASSERT_HPP 00010 #define GMTL_STATIC_ASSERT_HPP 00011 00012 namespace gmtl 00013 { 00019 template <int> struct CompileTimeError; 00020 template <> struct CompileTimeError<true> {}; 00021 } 00032 #define GMTL_STATIC_ASSERT(expr, msg) \ 00033 { gmtl::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; } 00034 00035 // -- OLD Static assert --- // 00036 // -- To be used if the new one causes problems -- // 00037 /* 00038 #include <gmtl/Defines.h> 00039 #include <gmtl/Util/Meta.h> 00040 00041 #ifdef __BORLANDC__ 00042 // 00043 // workaround for buggy integral-constant expression support: 00044 #define GMTL_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS 00045 #endif 00046 00047 namespace gmtl 00048 { 00049 00050 // HP aCC cannot deal with missing names for template value parameters 00051 template <bool x> struct STATIC_ASSERTION_FAILURE; 00052 00053 template <> struct STATIC_ASSERTION_FAILURE<true>{}; 00054 00055 // HP aCC cannot deal with missing names for template value parameters 00056 template<int x> struct static_assert_test{}; 00057 00058 } 00059 00060 // 00061 // Implicit instantiation requires that all member declarations be 00062 // instantiated, but that the definitions are *not* instantiated. 00063 // 00064 // It's not particularly clear how this applies to enum's or typedefs; 00065 // both are described as declarations [7.1.3] and [7.2] in the standard, 00066 // however some compilers use "delayed evaluation" of one or more of 00067 // these when implicitly instantiating templates. We use typedef declarations 00068 // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum 00069 // version gets better results from your compiler... 00070 // 00071 // Implementation: 00072 // Both of these versions rely on sizeof(incomplete_type) generating an error 00073 // message containing the name of the incomplete type. We use 00074 // "STATIC_ASSERTION_FAILURE" as the type name here to generate 00075 // an eye catching error message. The result of the sizeof expression is either 00076 // used as an enum initialiser, or as a template argument depending which version 00077 // is in use... 00078 // Note that the argument to the assert is explicitly cast to bool using old- 00079 // style casts: too many compilers currently have problems with static_cast 00080 // when used inside integral constant expressions. 00081 // 00082 #if !defined(GMTL_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) && !defined(__MWERKS__) 00083 #ifndef GMTL_MSVC 00084 #define GMTL_STATIC_ASSERT( B ) \ 00085 typedef ::gmtl::static_assert_test<\ 00086 sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ 00087 GMTL_JOIN(gmtl_static_assert_typedef_, __LINE__) 00088 #else 00089 // __LINE__ macro broken when -ZI is used see Q199057 00090 // fortunately MSVC ignores duplicate typedef's. 00091 #define GMTL_STATIC_ASSERT( B ) \ 00092 typedef ::gmtl::static_assert_test<\ 00093 sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >)\ 00094 > gmtl_static_assert_typedef_ 00095 #endif 00096 #else 00097 // alternative enum based implementation: 00098 #define GMTL_STATIC_ASSERT( B ) \ 00099 enum { GMTL_JOIN(gmtl_static_assert_enum_, __LINE__) \ 00100 = sizeof(::gmtl::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } 00101 #endif 00102 00103 */ 00104 00105 #endif // GMTL_STATIC_ASSERT_HPP