19 #ifndef LUNCHBOX_DEBUG_H
20 #define LUNCHBOX_DEBUG_H
22 #include <lunchbox/defines.h>
36 LUNCHBOX_API
void abort();
42 LUNCHBOX_API
void checkHeap();
50 LUNCHBOX_API std::ostream&
sysError( std::ostream& os );
63 LUNCHBOX_API std::string
backtrace(
const size_t skipFrames );
66 LUNCHBOX_API std::ostream&
backtrace( std::ostream& os );
68 LUNCHBOX_API std::string demangleTypeID(
const char* mangled );
71 # pragma warning( disable: 4100 ) // VS Bug
74 template<
class T >
inline std::string
className(
const T*
object )
75 {
return demangleTypeID(
typeid( *object ).name( )); }
78 template<
class T >
inline std::string
className(
const T&
object )
79 {
return demangleTypeID(
typeid(
object ).name( )); }
81 # pragma warning( default: 4100 )
93 template<
class T >
inline std::string
format(
const T* data,
const size_t num )
95 std::ostringstream os;
96 os << num <<
" " <<
className( data ) <<
" @ " << std::hex
97 << (
const void*)data <<
": 0x";
98 for(
size_t i = 0; i < num; ++i )
101 os <<
" " << std::endl;
102 os <<
' ' << data[i];
107 template<>
inline std::string
format(
const uint8_t* data,
const size_t num )
109 std::ostringstream os;
110 os << num <<
" bytes @ " << std::hex << (
const void*)data <<
": 0x";
112 for(
size_t i = 0; i < num; ++i )
115 os <<
" " << std::endl;
116 else if( (i % 8) == 0 )
118 os <<
' ' << std::setw(2) << int( data[i] );
123 template<>
inline std::string
format(
const void* data,
const size_t num )
124 {
return format( reinterpret_cast< const uint8_t* >( data ), num ); }
126 template<
class T >
inline std::string
format(
const std::vector< T >& data )
127 {
return format< T >( &data[0], data.size( )); }
132 # ifdef LB_RELEASE_ASSERT
133 # define LBASSERT(x) \
136 LBERROR << "##### Assert: " << #x << " #####" << std::endl \
137 << lunchbox::forceFlush; \
138 lunchbox::checkHeap(); \
140 # define LBASSERTINFO(x, info) \
143 LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
144 << std::endl << lunchbox::forceFlush; \
145 lunchbox::checkHeap(); \
147 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
150 # define LBASSERTINFO(x, info)
151 # define LBCHECK(x) { x; }
154 # define LBUNIMPLEMENTED { LBERROR << "Unimplemented code" << std::endl \
155 << lunchbox::forceFlush; }
156 # define LBUNREACHABLE { LBERROR << "Unreachable code" << std::endl \
157 << lunchbox::forceFlush; }
158 # define LBDONTCALL \
159 { LBERROR << "Code is not supposed to be called in this context" \
160 << std::endl << lunchbox::forceFlush; }
161 # define LBABORT( info ) { \
162 LBERROR << "##### Abort: " << info << " #####" << std::endl \
163 << lunchbox::forceFlush; }
167 # define LBASSERT(x) \
171 LBERROR << "Assert: " << #x << " "; \
174 lunchbox::checkHeap(); \
176 # define LBASSERTINFO(x, info) \
180 LBERROR << "Assert: " << #x << " [" << info << "] "; \
183 lunchbox::checkHeap(); \
186 # define LBUNIMPLEMENTED \
187 { LBERROR << "Unimplemented code in " << lunchbox::className( this ) \
190 # define LBUNREACHABLE \
191 { LBERROR << "Unreachable code in " << lunchbox::className( this ) \
194 # define LBDONTCALL \
195 { LBERROR << "Code is not supposed to be called in this context, type " \
196 << lunchbox::className( this ) << " " ; \
199 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
200 # define LBABORT( info ) { \
201 LBERROR << "Abort: " << info; \
205 #define LBSAFECAST( to, in ) static_cast< to >( in ); \
206 LBASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in )))
208 #endif //LUNCHBOX_DEBUG_H
LUNCHBOX_API std::ostream & sysError(std::ostream &os)
Print a textual description of the current system error.
LUNCHBOX_API std::string backtrace(const size_t skipFrames)
Get the current call stack.
std::string className(const T *object)
Print the RTTI name of the given class.
std::string format(const T *data, const size_t num)
Format the given array in a human-readable form.
This file contains logging classes.