// Header file.
#ifndef CUSTOM_ASSERT_H_
#define CUSTOM_ASSERT_H_
#include <string>
#include <fstream>
#ifndef __FUNCTION__
#define __FUNCTION__ "???"
#endif
#ifndef __FILE__
#define __FILE__ "???"
#endif
#ifndef __LINE__
#define __LINE__ 0
#endif
class CustomAssert
{
std::string m_Expression;
std::string m_Filename;
int m_Line;
std::ofstream m_File;
int m_Count;
public:
CustomAssert& CUSTOM_ASSERT_A;
CustomAssert& CUSTOM_ASSERT_B;
CustomAssert();
~CustomAssert();
template< typename T > CustomAssert& Print( const char* str, T val )
{
m_File<< "<font face="verdana" size="1" color="#DDDDFF"> "<< str;
m_File<< ": <font color="#dd88ff">"<< val<< "</font></font><br>";
return *this;
}
CustomAssert& Msg( const char* str );
void Break();
CustomAssert& operator () ( const char* expr, int line,
const char* func, const char* file );
};
extern CustomAssert g__SmartAssert__;
#define CUSTOM_ASSERT_A(x) CUSTOM_ASSERT_OP( x, B )
#define CUSTOM_ASSERT_B(x) CUSTOM_ASSERT_OP( x, A )
#define CUSTOM_ASSERT_OP( x, next ) CUSTOM_ASSERT_A.Print( #x, (x) ).CUSTOM_ASSERT_ ## next
#ifdef _DEBUG
#define Assert( expr )
if( (expr) );
else g__SmartAssert__( #expr, __LINE__, __FUNCTION__, __FILE__ ).CUSTOM_ASSERT_A
#else
#define Assert( expr )
if( true );
else g__SmartAssert__( #expr, __LINE__, __FUNCTION__, __FILE__ ).CUSTOM_ASSERT_A
#endif
#endif // CUSTOM_ASSERT_H_
// Source file
#include <cassert>
#include "assert.h"
#undef CUSTOM_ASSERT_A
#undef CUSTOM_ASSERT_B
CustomAssert g__SmartAssert__;
CustomAssert::CustomAssert()
: CUSTOM_ASSERT_A(*this), CUSTOM_ASSERT_B(*this)
{
m_File.open( "asserts.htm" );
m_File<< "<html>
<HEAD>
<CENTER>
<TITLE>Asserts</TITLE>
<H3><font face="verdana"color="ffffdd">Asserts</font></H3>
</CENTER>
</HEAD>
<BODY bgcolor="000000" text="ffffff">
<BR><BR>";
m_File.flush();
m_Count = 0;
}
CustomAssert::~CustomAssert()
{
m_File.close();
}
CustomAssert& CustomAssert::operator () ( const char* expr, int line,
const char* func, const char* file )
{
m_Expression = expr;
m_Filename = file;
m_Line = line;
static char buffer[32] = {0};
itoa( m_Count, buffer, 10 );
m_File<< "<p><b><u><font size="2" face="verdana" color="#ff0000">#";
m_File<< buffer;
m_File<< ": "<< expr<< "</font></u></b><br><br>";
m_File<< "<font size="1" face="verdana"><li>file: <font color="#C1F0FF">";
m_File<< file<< "</font><br>";
m_File<< "<li>line: <font color="#C1F0FF">"<< line<< "</font><br>";
m_File<< "<li>function: <font color="#C1F0FF">"<< func<< "</font><br></font>";
m_Count++;
return *this;
}
CustomAssert& CustomAssert::Msg( const char* str )
{
m_File<< "t"<< "<font size="1" face="verdana" color="#aaff88"><b>msg: </b>";
m_File<< "<font color="#ffaa88">"<< str<< "</font></font>";
return *this;
}
void CustomAssert::Break()
{
m_File.flush();
_assert( (void*)m_Expression.c_str(), (void*)m_Filename.c_str(), m_Line );
}
The code is readily compilable on msvc. Im not sure of other compilers because Im not sure if they have the same prototype to make an assertion box appear (Called in the Break() function). An example of using the assert follows:
int a = 0;
int b = 3;
int c = 32;
char* str = "string";
float f = 3.45f;
double d = 345.7;
Assert(0 == 1)(a)(B)(c).Msg("Passing ints");
Assert(3 == 4)(f)(d).Msg("Checking floats");
Assert(3 != 3)(str).Msg("Checking string variable");
Assert(0 && 0)(a)(B)(c)(f)(d)(str).Msg("Checking ALL and breaking").Break();












