/*****************************************************************************
 * $Id: gfx_assert.hh,v 1.21 2006/08/03 02:17:21 devel Exp $
 * @file
 * @author	Jim E. Brooks  http://www.jimbrooks.org
 * @brief	Assertion macros.
 *//*
 * LEGAL:	COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE (GPL).
 *****************************************************************************/

// make DEBUG=1 enables assertions, otherwise disabled.
#if ! DEBUG && ! defined(NDEBUG)
#define NDEBUG  // disable assert()
#endif
#include <assert.h>

// -----------------------------------------------------------------------------

#ifndef GFX_ASSERT_HH
#define GFX_ASSERT_HH 1

namespace gfx {

// ASSERT() macro expands a call via a function pointer to an assert handler,
// in order to print additional info to aid in debugging.
// GFX_SET_ASSERT_HANDLER() can set which assert handler.
#if DEBUG
void GFX_SET_ASSERT_HANDLER( void(*func)(bool cond, const char* fileName, int fileLine) );
extern void(*gGfxAssertHandler)(bool cond, const char* fileName, int fileLine);  // func ptr
// __LINE__ is a decimal constant, not a string.
#define ASSERT( COND ) gGfxAssertHandler( (COND), __FILE__, __LINE__ )
#else
#define ASSERT( COND )
#endif

// ASSERT2() is for pedantic checks that would slow down the normal debug build.
#if DEBUG == 2  // extra debug level
#define ASSERT2( COND ) ASSERT( (COND) )
#else
#define ASSERT2( COND )
#endif

// Assert that a function runs only once.
#if DEBUG
#define ASSERT_RUN_ONCE {{ static int once = 0; ++once; ASSERT( once == 1 ); }}
#else
#define ASSERT_RUN_ONCE
#endif

// AssertOr*() is for error conditions where the program might be able to continue.
// The OR case is in case assert() is disabled by NDEBUG.
#ifndef ASSERT_OR_RETURN
#define ASSERT_OR_RETURN( COND ) \
{ \
	ASSERT( (COND) ); \
	if ( !(COND) ) return; \
}
#define ASSERT_OR_RETURN_VAL( COND, VAL ) \
{ \
	ASSERT( (COND) ); \
	if ( !(COND) ) return (VAL); \
}
#define ASSERT_OR_GOTO( COND, LABEL ) \
{ \
	ASSERT( (COND) ); \
	if ( !(COND) ) goto (LABEL); \
}
#endif // ASSERT_OR_RETURN

} // namespace gfx

#endif // GFX_ASSERT_HH
