| 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 | #ifdef __BORLANDC__ | 
|---|
| 21 | // | 
|---|
| 22 | // workaround for buggy integral-constant expression support: | 
|---|
| 23 | #define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS | 
|---|
| 24 | #endif | 
|---|
| 25 |  | 
|---|
| 26 | #if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4)) | 
|---|
| 27 | // gcc 3.3 and 3.4 don't produce good error messages with the default version: | 
|---|
| 28 | #  define BOOST_SA_GCC_WORKAROUND | 
|---|
| 29 | #endif | 
|---|
| 30 |  | 
|---|
| 31 | namespace boost{ | 
|---|
| 32 |  | 
|---|
| 33 | // HP aCC cannot deal with missing names for template value parameters | 
|---|
| 34 | template <bool x> struct STATIC_ASSERTION_FAILURE; | 
|---|
| 35 |  | 
|---|
| 36 | template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; | 
|---|
| 37 |  | 
|---|
| 38 | // HP aCC cannot deal with missing names for template value parameters | 
|---|
| 39 | template<int x> struct static_assert_test{}; | 
|---|
| 40 |  | 
|---|
| 41 | } | 
|---|
| 42 |  | 
|---|
| 43 | // | 
|---|
| 44 | // Implicit instantiation requires that all member declarations be | 
|---|
| 45 | // instantiated, but that the definitions are *not* instantiated. | 
|---|
| 46 | // | 
|---|
| 47 | // It's not particularly clear how this applies to enum's or typedefs; | 
|---|
| 48 | // both are described as declarations [7.1.3] and [7.2] in the standard, | 
|---|
| 49 | // however some compilers use "delayed evaluation" of one or more of | 
|---|
| 50 | // these when implicitly instantiating templates.  We use typedef declarations | 
|---|
| 51 | // by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum | 
|---|
| 52 | // version gets better results from your compiler... | 
|---|
| 53 | // | 
|---|
| 54 | // Implementation: | 
|---|
| 55 | // Both of these versions rely on sizeof(incomplete_type) generating an error | 
|---|
| 56 | // message containing the name of the incomplete type.  We use | 
|---|
| 57 | // "STATIC_ASSERTION_FAILURE" as the type name here to generate | 
|---|
| 58 | // an eye catching error message.  The result of the sizeof expression is either | 
|---|
| 59 | // used as an enum initialiser, or as a template argument depending which version | 
|---|
| 60 | // is in use... | 
|---|
| 61 | // Note that the argument to the assert is explicitly cast to bool using old- | 
|---|
| 62 | // style casts: too many compilers currently have problems with static_cast | 
|---|
| 63 | // when used inside integral constant expressions. | 
|---|
| 64 | // | 
|---|
| 65 | #if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS) | 
|---|
| 66 |  | 
|---|
| 67 | #if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) | 
|---|
| 68 | // __LINE__ macro broken when -ZI is used see Q199057 | 
|---|
| 69 | // fortunately MSVC ignores duplicate typedef's. | 
|---|
| 70 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 71 |    typedef ::boost::static_assert_test<\ | 
|---|
| 72 |       sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)\ | 
|---|
| 73 |       > boost_static_assert_typedef_ | 
|---|
| 74 | #elif defined(BOOST_MSVC) | 
|---|
| 75 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 76 |    typedef ::boost::static_assert_test<\ | 
|---|
| 77 |       sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ | 
|---|
| 78 |          BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__) | 
|---|
| 79 | #elif defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND) | 
|---|
| 80 | // agurt 15/sep/02: a special care is needed to force Intel C++ issue an error  | 
|---|
| 81 | // instead of warning in case of failure | 
|---|
| 82 | # define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 83 |     typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \ | 
|---|
| 84 |         [ ::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >::value ] | 
|---|
| 85 | #elif defined(__sgi) | 
|---|
| 86 | // special version for SGI MIPSpro compiler | 
|---|
| 87 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 88 |    BOOST_STATIC_CONSTANT(bool, \ | 
|---|
| 89 |      BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \ | 
|---|
| 90 |    typedef ::boost::static_assert_test<\ | 
|---|
| 91 |      sizeof(::boost::STATIC_ASSERTION_FAILURE< \ | 
|---|
| 92 |        BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\ | 
|---|
| 93 |          BOOST_JOIN(boost_static_assert_typedef_, __LINE__) | 
|---|
| 94 | #elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003) | 
|---|
| 95 | // special version for CodeWarrior <= 8.x | 
|---|
| 96 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 97 |    BOOST_STATIC_CONSTANT(int, \ | 
|---|
| 98 |      BOOST_JOIN(boost_static_assert_test_, __LINE__) = \ | 
|---|
| 99 |        sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) ) | 
|---|
| 100 | #else | 
|---|
| 101 | // generic version | 
|---|
| 102 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 103 |    typedef ::boost::static_assert_test<\ | 
|---|
| 104 |       sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >)>\ | 
|---|
| 105 |          BOOST_JOIN(boost_static_assert_typedef_, __LINE__) | 
|---|
| 106 | #endif | 
|---|
| 107 |  | 
|---|
| 108 | #else | 
|---|
| 109 | // alternative enum based implementation: | 
|---|
| 110 | #define BOOST_STATIC_ASSERT( B ) \ | 
|---|
| 111 |    enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \ | 
|---|
| 112 |       = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) } | 
|---|
| 113 | #endif | 
|---|
| 114 |  | 
|---|
| 115 |  | 
|---|
| 116 | #endif // BOOST_STATIC_ASSERT_HPP | 
|---|
| 117 |  | 
|---|
| 118 |  | 
|---|