Lunchbox  1.6.0
debug.h
00001 
00002 /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #ifndef LUNCHBOX_DEBUG_H
00019 #define LUNCHBOX_DEBUG_H
00020 
00021 #include <lunchbox/defines.h>
00022 #include <lunchbox/log.h>
00023 
00024 #include <typeinfo>
00025 
00026 // assertions
00027 // #define LB_RELEASE_ASSERT
00028 
00029 namespace lunchbox
00030 {
00035 LUNCHBOX_API void abort();
00036 
00041 LUNCHBOX_API void checkHeap();
00042 
00049 LUNCHBOX_API std::ostream& sysError( std::ostream& os );
00050 
00057 LUNCHBOX_API std::ostream& backtrace( std::ostream& os );
00058 
00059 LUNCHBOX_API std::string demangleTypeID( const char* mangled ); 
00060 
00062 template< class T > inline std::string className( T* object )
00063     { return demangleTypeID( typeid( *object ).name( )); }
00064 
00066 template< class T > inline std::string className( T& object )
00067     { return demangleTypeID( typeid( object ).name( )); }
00068 }
00069 
00070 #ifdef NDEBUG
00071 #  ifdef LB_RELEASE_ASSERT
00072 #    define LBASSERT(x)                                                 \
00073     {                                                                   \
00074         if( !(x) )                                                      \
00075             LBERROR << "##### Assert: " << #x << " #####" << std::endl  \
00076                     << lunchbox::forceFlush;                            \
00077         lunchbox::checkHeap();                                          \
00078     }
00079 #    define LBASSERTINFO(x, info)                                       \
00080     {                                                                   \
00081         if( !(x) )                                                      \
00082             LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
00083                     << std::endl << lunchbox::forceFlush;               \
00084         lunchbox::checkHeap();                                          \
00085     }
00086 #    define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
00087 #  else
00088 #    define LBASSERT(x)
00089 #    define LBASSERTINFO(x, info)
00090 #    define LBCHECK(x) { x; }
00091 #  endif
00092 
00093 #  define LBUNIMPLEMENTED { LBERROR << "Unimplemented code" << std::endl \
00094                                     << lunchbox::forceFlush; }
00095 #  define LBUNREACHABLE   { LBERROR << "Unreachable code" << std::endl  \
00096                                     << lunchbox::forceFlush; }
00097 #  define LBDONTCALL                                                    \
00098     { LBERROR << "Code is not supposed to be called in this context"    \
00099               << std::endl << lunchbox::forceFlush; }
00100 #  define LBABORT( info ) {                                         \
00101         LBERROR << "##### Abort: " << info << " #####" << std::endl \
00102                 << lunchbox::forceFlush; }
00103 
00104 #else // NDEBUG
00105 
00106 #  define LBASSERT(x)                                                   \
00107     {                                                                   \
00108         if( !(x) )                                                      \
00109         {                                                               \
00110             LBERROR << "Assert: " << #x << " ";                         \
00111             lunchbox::abort();                                          \
00112         }                                                               \
00113         lunchbox::checkHeap();                                          \
00114     } 
00115 #  define LBASSERTINFO(x, info)                                         \
00116     {                                                                   \
00117         if( !(x) )                                                      \
00118         {                                                               \
00119             LBERROR << "Assert: " << #x << " [" << info << "] ";        \
00120             lunchbox::abort();                                          \
00121         }                                                               \
00122         lunchbox::checkHeap();                                          \
00123     }
00124 
00125 #  define LBUNIMPLEMENTED                                               \
00126     { LBERROR << "Unimplemented code in " << lunchbox::className( this ) \
00127               << " ";                                                   \
00128         lunchbox::abort(); }
00129 #  define LBUNREACHABLE                                                 \
00130     { LBERROR << "Unreachable code in " << lunchbox::className( this )  \
00131               << " ";                                                   \
00132         lunchbox::abort(); }
00133 #  define LBDONTCALL                                                    \
00134     { LBERROR << "Code is not supposed to be called in this context, type " \
00135               << lunchbox::className( this ) << " " ;                   \
00136         lunchbox::abort(); }
00137 
00138 #  define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
00139 #  define LBABORT( info ) {                                             \
00140         LBERROR << "Abort: " << info;                                   \
00141         lunchbox::abort(); }
00142 #endif // NDEBUG
00143 
00144 #define LBSAFECAST( to, in ) static_cast< to >( in );   \
00145     LBASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in )))
00146 
00147 #endif //LUNCHBOX_DEBUG_H