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 ); }
129 # ifdef LB_RELEASE_ASSERT
130 # define LBASSERT(x) \
133 LBERROR << "##### Assert: " << #x << " #####" << std::endl \
134 << lunchbox::forceFlush; \
135 lunchbox::checkHeap(); \
137 # define LBASSERTINFO(x, info) \
140 LBERROR << "##### Assert: " << #x << " [" << info << "] #####" \
141 << std::endl << lunchbox::forceFlush; \
142 lunchbox::checkHeap(); \
144 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
147 # define LBASSERTINFO(x, info)
148 # define LBCHECK(x) { x; }
151 # define LBUNIMPLEMENTED { LBERROR << "Unimplemented code" << std::endl \
152 << lunchbox::forceFlush; }
153 # define LBUNREACHABLE { LBERROR << "Unreachable code" << std::endl \
154 << lunchbox::forceFlush; }
155 # define LBDONTCALL \
156 { LBERROR << "Code is not supposed to be called in this context" \
157 << std::endl << lunchbox::forceFlush; }
158 # define LBABORT( info ) { \
159 LBERROR << "##### Abort: " << info << " #####" << std::endl \
160 << lunchbox::forceFlush; }
164 # define LBASSERT(x) \
168 LBERROR << "Assert: " << #x << " "; \
171 lunchbox::checkHeap(); \
173 # define LBASSERTINFO(x, info) \
177 LBERROR << "Assert: " << #x << " [" << info << "] "; \
180 lunchbox::checkHeap(); \
183 # define LBUNIMPLEMENTED \
184 { LBERROR << "Unimplemented code in " << lunchbox::className( this ) \
187 # define LBUNREACHABLE \
188 { LBERROR << "Unreachable code in " << lunchbox::className( this ) \
191 # define LBDONTCALL \
192 { LBERROR << "Code is not supposed to be called in this context, type " \
193 << lunchbox::className( this ) << " " ; \
196 # define LBCHECK(x) { const bool eqOk = x; LBASSERTINFO( eqOk, #x ) }
197 # define LBABORT( info ) { \
198 LBERROR << "Abort: " << info; \
202 #define LBSAFECAST( to, in ) static_cast< to >( in ); \
203 LBASSERT( in == 0 || dynamic_cast< to >( static_cast< to >( in )))
205 #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.