Menu

staticwarning.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00004  *                    2010 Marcus Förster <MarcusFoerster1@gmx.de>
00005  * All rights reserved.
00006  *
00007  *    Redistribution and use in source and binary forms, with or without
00008  *    modification, are permitted provided that the following conditions
00009  *    are met:
00010  *
00011  *    * Redistributions of source code must retain the above copyright
00012  *      notice, this list of conditions and the following disclaimer.
00013  *
00014  *    * Redistributions in binary form must reproduce the above copyright
00015  *      notice, this list of conditions and the following disclaimer in
00016  *      the documentation and/or other materials provided with the
00017  *      distribution.
00018  *
00019  *    * Neither the name of the copyright holders nor the names of
00020  *      contributors may be used to endorse or promote products derived
00021  *      from this software without specific prior written permission.
00022  *
00023  *
00024  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00025  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  *
00037  * $Id$
00038  *
00039  ******************************************************************************/
00040 
00041 #ifndef _STATIC_WARNING_H_
00042 #define _STATIC_WARNING_H_
00043 
00044 #define JOIN( X, Y ) DO_JOIN( X, Y )
00045 #define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
00046 #define DO_JOIN2( X, Y ) X##Y
00047 
00048 #include "boost/mpl/eval_if.hpp"
00049 
00050 namespace failed_assertion {
00051 
00052     template<int>
00053     struct CompileTimeWarningTest;
00054 
00055     struct args;
00056 }
00057 
00058 #if defined __GNUC__
00059 
00060 namespace failed_assertion {
00061 
00062     struct Integer {
00063         typedef Integer type;
00064         static const unsigned int w=8;
00065     };
00066 
00067 
00068     template<typename>
00069     struct _warning_ {
00070         typedef _warning_ type;
00071         enum _ {w};
00072     };
00073 
00074 }
00075 #define FAMOUSO_STATIC_ASSERT_WARNING(expr, msg, types)                     \
00076     struct JOIN(JOIN(_failed_assertion_in_line_,__LINE__),_with_message_) { \
00077         enum JOIN(JOIN(__,msg),__) {w};                                     \
00078         static void args types { }                                          \
00079     };                                                                      \
00080     typedef ::failed_assertion::CompileTimeWarningTest<                     \
00081                 JOIN(                                                       \
00082                     JOIN(                                                   \
00083                         _failed_assertion_in_line_,__LINE__                 \
00084                     ),                                                      \
00085                     _with_message_                                          \
00086                 )::w                                                        \
00087                     ==                                                      \
00088                 boost::mpl::eval_if_c<                                      \
00089                     expr,                                                   \
00090                     ::failed_assertion::Integer,                            \
00091                     ::failed_assertion::_warning_<                          \
00092                         void**** (::failed_assertion::args::****) types     \
00093                     >                                                       \
00094                 >::type::w                                                  \
00095             > JOIN(__warning_in_line__,__LINE__)
00096 
00097 #elif defined _MSC_VER
00098 
00099 namespace failed_assertion {
00100 
00101     template<typename,bool>
00102     struct _warning_ {
00103         typedef _warning_ type;
00104     };
00105 }
00106 
00107 #define FAMOUSO_STATIC_ASSERT_WARNING(expr, msg, types)                     \
00108     __pragma(warning (push, 1))                                             \
00109     __pragma(warning (1:4263))                                              \
00110     struct JOIN(_failed_assertion_line_,__LINE__)              {            \
00111         struct _ {                                                          \
00112             virtual void _ ## msg ## _( ::failed_assertion::_warning_<      \
00113                         void**** (::failed_assertion::args::****) types,    \
00114                         true                                                \
00115                    >) = 0;                                                  \
00116         };                                                                  \
00117         struct __ : _ {                                                     \
00118             void _ ## msg ## _(::failed_assertion::_warning_<               \
00119                         void**** (::failed_assertion::args::****) types,    \
00120                         (expr)                                              \
00121                    > );                                                     \
00122         };                                                                  \
00123         typedef ::failed_assertion::CompileTimeWarningTest<sizeof(__)> ___; \
00124     };                                                                      \
00125     __pragma(warning (pop))                                                 \
00126     typedef ::failed_assertion::CompileTimeWarningTest<                     \
00127                 sizeof(JOIN(_failed_assertion_line_,__LINE__))              \
00128             > JOIN(__,__LINE__)
00129 
00130 
00131 #else
00132 
00133 #warning "Compiler is not supported by the FAMOUSO_STATIC_ASSERT_WARNING macro"
00134 #define FAMOUSO_STATIC_ASSERT_WARNING(expr, msg, types)
00135 
00136 #endif
00137 
00138 #endif