#ifndef DBG_H
#define DBG_H
#pragma once
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include "basetypes.h"
#include "platform.h"
#include <vstdlib/strtools.h>
BEGIN_TIER0_NAMESPACE
#ifndef _CERT
#define DBGFLAG_ASSERT
#endif
#define DBGFLAG_ASSERTFATAL
template <typename... A>
static auto DbgMsgCountArgsT( A... a ) -> char(&)[sizeof...( a )];
template <bool bFatal, bool bSingleRawStringArgument> class AssertMsgHelper;
template <> class AssertMsgHelper<true, true>
{
public:
static void AssertFailed( const char* pstrFile, unsigned int nLine, const char *pMsg );
};
template <> class AssertMsgHelper<false, true>
{
public:
static void AssertFailed( const char* pstrFile, unsigned int nLine, const char *pMsg );
};
template <> class AssertMsgHelper<true, false>
{
public:
static void AssertFailed( const char* pstrFile, unsigned int nLine, PRINTF_FORMAT_STRING const char *pFmt, ... ) FMTFUNCTION( 3, 4 );
};
template <> class AssertMsgHelper<false, false>
{
public:
static void AssertFailed( const char* pstrFile, unsigned int nLine, PRINTF_FORMAT_STRING const char *pFmt, ... ) FMTFUNCTION( 3, 4 );
};
#ifdef _PREFAST_
#define _AssertMsgSmall( _exp, _bFatal, _fmt, ... ) do { __analysis_assume( !!(_exp) ); _fmt; } while (0)
#define _AssertMsgOnce( _exp, _bFatal, _fmt, ... ) do { __analysis_assume( !!(_exp) ); _fmt; } while (0)
#else
#define _AssertMsgSmall( _exp, _bFatal, ... ) \
do { \
if ( !(_exp) ) \
{ \
AssertMsgHelper< _bFatal, sizeof( DbgMsgCountArgsT( __VA_ARGS__ ) ) == 1 >::AssertFailed( __FILE__, __LINE__, __VA_ARGS__ ); \
} \
} while (0)
#define _AssertMsgOnce( _exp, _bFatal, ... ) \
do { \
static bool fAsserted = false; \
if ( !fAsserted && !(_exp) ) \
{ \
fAsserted = true; \
AssertMsgHelper< _bFatal, sizeof( DbgMsgCountArgsT( __VA_ARGS__ ) ) == 1 >::AssertFailed( __FILE__, __LINE__, __VA_ARGS__ ); \
} \
} while (0)
#endif
#define AssertFatal( _exp ) _AssertMsgSmall( _exp, true, "Fatal Assertion Failed: " #_exp )
#define AssertFatalMsg( _exp, ... ) _AssertMsgSmall( _exp, true, __VA_ARGS__ )
#define VerifyFatal( _exp ) AssertFatal( _exp )
#ifdef DBGFLAG_ASSERT
#define Assert( _exp ) _AssertMsgSmall( _exp, false, "Assertion Failed: " #_exp )
#define AssertMsg( _exp, ... ) _AssertMsgSmall( _exp, false, __VA_ARGS__ )
#define AssertMsgFormatted( _exp, _msg ) _AssertMsgSmall( _exp, false, _msg )
#define AssertOnce( _exp ) _AssertMsgOnce( _exp, false, "Assertion Failed: " #_exp )
#define AssertMsgOnce( _exp, ... ) _AssertMsgOnce( _exp, false, __VA_ARGS__ )
#else
#define Assert( _exp ) ((void)0)
#define AssertMsg( _exp, _msg, ... ) ((void)0)
#define AssertMsgFormatted( _exp, _msg ) ((void)0)
#define AssertOnce( _exp ) ((void)0)
#define AssertMsgOnce( _exp, _msg, ... ) ((void)0)
#endif
#if defined(_DEBUG) && defined( DBGFLAG_ASSERT )
#define DbgAssert( _exp ) Assert( _exp )
#define DbgAssertMsg( _exp, ... ) AssertMsg( _exp, __VA_ARGS__ )
#define DbgVerify( _exp ) Assert( _exp )
#else
#define DbgAssert( _exp ) ( (void)0 )
#define DbgAssertMsg( _exp, ... ) ( (void)0 )
#define DbgVerify( _exp ) (void)(_exp)
#endif
#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, _msg, a1 )
#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, _msg, a1, a2 )
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, _msg, a1, a2, a3 )
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, _msg, a1, a2, a3, a4 )
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5 )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 )
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )
#define DbgAssertMsg1( _exp, _msg, a1 ) DbgAssertMsg( _exp, _msg, a1 )
#define DbgAssertMsg2( _exp, _msg, a1, a2 ) DbgAssertMsg( _exp, _msg, a1, a2 )
#define DbgAssertMsg3( _exp, _msg, a1, a2, a3 ) DbgAssertMsg( _exp, _msg, a1, a2, a3 )
template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
{
#if RTTIEnabled()
DbgAssert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
#endif
return static_cast<DEST_POINTER_TYPE>(pSource);
}
#define Plat_FatalError( ... ) AssertFatalMsg( false, __VA_ARGS__ )
END_TIER0_NAMESPACE
#endif