DevMaster.net Forums
[[ Home | Forums | 3D Engines Database | Wiki | Articles/Tutorials | Game Dev Jobs | IRC Chat Network | Contact Us ]]

Go Back   DevMaster.net Forums > Site Discussions > Code & Snapshot Discussion
User Name
Password
Register FAQ Members List Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
Old 09-11-2004, 07:18 PM   #1
bladder
DevMaster Staff
 
bladder's Avatar
 
Join Date: Sep 2003
Location: Hell
Posts: 1,109
Default

I read this article a while back about using recursive preprocessing to enhance the capabilities of an assertion. The article was written by one Andrei Alexandrescu, the author of Modern C++ Design. Here's a direct link to the article that explains the recursive process in details, and the following is the full and IMO minimal implementation of it. This is an excellent tool to have with you. It greatly increases the information you can get out of an assertion.

// Header file.
Code:
#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
Code:
#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:

Code:
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();
___________________________________________
- TripleBuffer
- Me blog
bladder is offline   Reply With Quote
Old 09-12-2004, 07:33 PM   #2
Francois Hamel
Valued Member
 
Francois Hamel's Avatar
 
Join Date: Aug 2004
Location: Quebec, Canada
Posts: 109
Default

interresting...
but the style is very ugly
___________________________________________
I post with style, do you?
http://fhamel.blogspot.com/
Francois Hamel is offline   Reply With Quote
Old 09-12-2004, 10:39 PM   #3
davepermen
Senior Member
 
davepermen's Avatar
 
Join Date: Jan 2003
Location: Switzerland
Posts: 1,333
Default

i've played around with such code for a while, by myself, too.. i wouldn't have mixed it with the logging directly, thought.. but for the example purpose it's fine..
___________________________________________
davepermen.net
-Loving a Person is having the wish to see this Person happy, no matter what that means to yourself.
-No matter what it means to myself....
davepermen is offline   Reply With Quote
Old 09-15-2004, 06:05 AM   #4
knackered3
New Member
 
Join Date: Sep 2004
Posts: 20
Default

Code:
m_File<< "<font face="verdana" size="1" color="#DDDDFF"> "<< str;

doesn't compile out of the box.
you're missing some \ where you have quotes in quotes.
knackered3 is offline   Reply With Quote
Old 09-15-2004, 08:05 AM   #5
Dia Kharrat
DevMaster Staff
 
Join Date: Jan 2003
Posts: 1,201
Default

knackered: the code initially contained the backslashes, but it seems a bug in the syntax highlighter removed them. This has been fixed, but hasn't been updated on the site yet.
Dia Kharrat is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Forum Jump


All times are GMT -7. The time now is 09:51 AM.


Powered by vBulletin
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.