Jeff Thompson | f7d4994 | 2013-08-01 16:47:40 -0700 | [diff] [blame^] | 1 | // (C) Copyright John Maddock 2000. |
| 2 | // Use, modification and distribution are subject to the |
| 3 | // Boost Software License, Version 1.0. (See accompanying file |
| 4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 5 | |
| 6 | // See http://www.boost.org/libs/static_assert for documentation. |
| 7 | |
| 8 | /* |
| 9 | Revision history: |
| 10 | 02 August 2000 |
| 11 | Initial version. |
| 12 | */ |
| 13 | |
| 14 | #ifndef BOOST_STATIC_ASSERT_HPP |
| 15 | #define BOOST_STATIC_ASSERT_HPP |
| 16 | |
| 17 | #include <boost/config.hpp> |
| 18 | #include <boost/detail/workaround.hpp> |
| 19 | |
| 20 | #if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) |
| 21 | // |
| 22 | // This is horrible, but it seems to be the only we can shut up the |
| 23 | // "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]" |
| 24 | // warning that get spewed out otherwise in non-C++11 mode. |
| 25 | // |
| 26 | #pragma GCC system_header |
| 27 | #endif |
| 28 | |
| 29 | #ifndef BOOST_NO_CXX11_STATIC_ASSERT |
| 30 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 31 | # define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__) |
| 32 | # else |
| 33 | # define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) |
| 34 | # endif |
| 35 | #else |
| 36 | # define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B ) |
| 37 | #endif |
| 38 | |
| 39 | #ifdef __BORLANDC__ |
| 40 | // |
| 41 | // workaround for buggy integral-constant expression support: |
| 42 | #define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS |
| 43 | #endif |
| 44 | |
| 45 | #if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) |
| 46 | // gcc 3.3 and 3.4 don't produce good error messages with the default version: |
| 47 | # define BOOST_SA_GCC_WORKAROUND |
| 48 | #endif |
| 49 | |
| 50 | // |
| 51 | // If the compiler issues warnings about old C style casts, |
| 52 | // then enable this: |
| 53 | // |
| 54 | #if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))) |
| 55 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 56 | # define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) == 0 ? false : true) |
| 57 | # else |
| 58 | # define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) == 0 ? false : true) |
| 59 | # endif |
| 60 | #else |
| 61 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 62 | # define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__) |
| 63 | # else |
| 64 | # define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x) |
| 65 | # endif |
| 66 | #endif |
| 67 | // |
| 68 | // If the compiler warns about unused typedefs then enable this: |
| 69 | // |
| 70 | #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) |
| 71 | # define BOOST_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) |
| 72 | #else |
| 73 | # define BOOST_STATIC_ASSERT_UNUSED_ATTRIBUTE |
| 74 | #endif |
| 75 | |
| 76 | #ifndef BOOST_NO_CXX11_STATIC_ASSERT |
| 77 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 78 | # define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__) |
| 79 | # else |
| 80 | # define BOOST_STATIC_ASSERT( B ) static_assert(B, #B) |
| 81 | # endif |
| 82 | #else |
| 83 | |
| 84 | namespace ndnboost{ |
| 85 | |
| 86 | // HP aCC cannot deal with missing names for template value parameters |
| 87 | template <bool x> struct STATIC_ASSERTION_FAILURE; |
| 88 | |
| 89 | template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; |
| 90 | |
| 91 | // HP aCC cannot deal with missing names for template value parameters |
| 92 | template<int x> struct static_assert_test{}; |
| 93 | |
| 94 | } |
| 95 | |
| 96 | // |
| 97 | // Implicit instantiation requires that all member declarations be |
| 98 | // instantiated, but that the definitions are *not* instantiated. |
| 99 | // |
| 100 | // It's not particularly clear how this applies to enum's or typedefs; |
| 101 | // both are described as declarations [7.1.3] and [7.2] in the standard, |
| 102 | // however some compilers use "delayed evaluation" of one or more of |
| 103 | // these when implicitly instantiating templates. We use typedef declarations |
| 104 | // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum |
| 105 | // version gets better results from your compiler... |
| 106 | // |
| 107 | // Implementation: |
| 108 | // Both of these versions rely on sizeof(incomplete_type) generating an error |
| 109 | // message containing the name of the incomplete type. We use |
| 110 | // "STATIC_ASSERTION_FAILURE" as the type name here to generate |
| 111 | // an eye catching error message. The result of the sizeof expression is either |
| 112 | // used as an enum initialiser, or as a template argument depending which version |
| 113 | // is in use... |
| 114 | // Note that the argument to the assert is explicitly cast to bool using old- |
| 115 | // style casts: too many compilers currently have problems with static_cast |
| 116 | // when used inside integral constant expressions. |
| 117 | // |
| 118 | #if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) |
| 119 | |
| 120 | #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) |
| 121 | // __LINE__ macro broken when -ZI is used see Q199057 |
| 122 | // fortunately MSVC ignores duplicate typedef's. |
| 123 | #define BOOST_STATIC_ASSERT( B ) \ |
| 124 | typedef ::ndnboost::static_assert_test<\ |
| 125 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)\ |
| 126 | > boost_static_assert_typedef_ |
| 127 | #elif defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) |
| 128 | #define BOOST_STATIC_ASSERT( B ) \ |
| 129 | typedef ::ndnboost::static_assert_test<\ |
| 130 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\ |
| 131 | BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) |
| 132 | #elif defined(BOOST_MSVC) |
| 133 | #define BOOST_STATIC_ASSERT(...) \ |
| 134 | typedef ::ndnboost::static_assert_test<\ |
| 135 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\ |
| 136 | BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) |
| 137 | #elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && defined(BOOST_NO_CXX11_VARIADIC_MACROS) |
| 138 | // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error |
| 139 | // instead of warning in case of failure |
| 140 | # define BOOST_STATIC_ASSERT( B ) \ |
| 141 | typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ |
| 142 | [ ::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ] |
| 143 | #elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND)) && !defined(BOOST_NO_CXX11_VARIADIC_MACROS) |
| 144 | // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error |
| 145 | // instead of warning in case of failure |
| 146 | # define BOOST_STATIC_ASSERT(...) \ |
| 147 | typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ |
| 148 | [ ::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ] |
| 149 | #elif defined(__sgi) |
| 150 | // special version for SGI MIPSpro compiler |
| 151 | #define BOOST_STATIC_ASSERT( B ) \ |
| 152 | BOOST_STATIC_CONSTANT(bool, \ |
| 153 | BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ |
| 154 | typedef ::ndnboost::static_assert_test<\ |
| 155 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< \ |
| 156 | BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ |
| 157 | BOOST_JOIN(boost_static_assert_typedef_, __LINE__) |
| 158 | #elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) |
| 159 | // special version for CodeWarrior <= 8.x |
| 160 | #define BOOST_STATIC_ASSERT( B ) \ |
| 161 | BOOST_STATIC_CONSTANT(int, \ |
| 162 | BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ |
| 163 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) ) |
| 164 | #else |
| 165 | // generic version |
| 166 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 167 | # define BOOST_STATIC_ASSERT( ... ) \ |
| 168 | typedef ::ndnboost::static_assert_test<\ |
| 169 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\ |
| 170 | BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_STATIC_ASSERT_UNUSED_ATTRIBUTE |
| 171 | # else |
| 172 | # define BOOST_STATIC_ASSERT( B ) \ |
| 173 | typedef ::ndnboost::static_assert_test<\ |
| 174 | sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\ |
| 175 | BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_STATIC_ASSERT_UNUSED_ATTRIBUTE |
| 176 | # endif |
| 177 | #endif |
| 178 | |
| 179 | #else |
| 180 | // alternative enum based implementation: |
| 181 | # ifndef BOOST_NO_CXX11_VARIADIC_MACROS |
| 182 | # define BOOST_STATIC_ASSERT( ... ) \ |
| 183 | enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ |
| 184 | = sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) } |
| 185 | # else |
| 186 | # define BOOST_STATIC_ASSERT(B) \ |
| 187 | enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ |
| 188 | = sizeof(::ndnboost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } |
| 189 | # endif |
| 190 | #endif |
| 191 | #endif // defined(BOOST_NO_CXX11_STATIC_ASSERT) |
| 192 | |
| 193 | #endif // BOOST_STATIC_ASSERT_HPP |
| 194 | |
| 195 | |