Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_MACROS_H
Toshihiro Shimizu 890ddd
#define TCG_MACROS_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \file     macros.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    This file contains some useful macros that can be used
Toshihiro Shimizu 890ddd
            with tcg and generic C++ projects.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \def      TCG_ASSERT(assertion, failure_expr)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    The TCG_ASSERT instruction is an assertion that also provides 
Toshihiro Shimizu 890ddd
            a valid failure statement in case the asserted expression fails.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \details  Assert statements are used to enforce pre- and post-conditions to
Toshihiro Shimizu 890ddd
            algorithms, in a way that is \b not intended to be broken - in
Toshihiro Shimizu 890ddd
            other words, after a failed assert statement we should expect
Toshihiro Shimizu 890ddd
            nothing more than undefined behavior. The assert statement itself
Toshihiro Shimizu 890ddd
            will signal a failed expression,  and then will force the
Toshihiro Shimizu 890ddd
            program to quit <\I>.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            However, there exist cases in which at the same time:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              \li It is \a known that a pre/post-condition could be possibly broken
Toshihiro Shimizu 890ddd
              \li It should still be considered an error
Toshihiro Shimizu 890ddd
              \li Yet, a worst-case bail-out policy must be provided
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
            When this happen, you should:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              \li Feel offended - it should really not<\B> happen. Errors in
Toshihiro Shimizu 890ddd
                  meeting requirements should never be tolerated
Toshihiro Shimizu 890ddd
              \li Use TCG_ASSERT. It does not solve things, but is a simple
Toshihiro Shimizu 890ddd
                  statement and defines a trackable (grep-able) string in the project
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define TCG_ASSERT(assertion, failure_expr) \
Toshihiro Shimizu 890ddd
                                            \
Toshihiro Shimizu 890ddd
	if (!(assertion)) {                     \
Toshihiro Shimizu 890ddd
		assert(assertion);                  \
Toshihiro Shimizu 890ddd
		failure_expr;                       \
Toshihiro Shimizu 890ddd
	} else                                  \
Toshihiro Shimizu 890ddd
	(void)0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \def      TCG_JOIN(A, B)
Toshihiro Shimizu 890ddd
  \brief    Pastes the supplied arguments together, even when the arguments
Toshihiro Shimizu 890ddd
            are macros themselves (typically seen with __LINE__)
Toshihiro Shimizu 890ddd
  \sa       Taken from BOOST_JOIN(A, B)
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
#define TCG_DO_JOIN2(A, B) A##B
Toshihiro Shimizu 890ddd
#define TCG_DO_JOIN(A, B) TCG_DO_JOIN2(A, B) // Argument macro expansion here
Toshihiro Shimizu 890ddd
#define TCG_JOIN(A, B) TCG_DO_JOIN(A, B)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \def      TCG_STATIC_ASSERT(expr)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    Performs a compile-time check of the specified assertion.
Toshihiro Shimizu 890ddd
  \warning  This macro uses the file's line number to name a hidden structure.
Toshihiro Shimizu 890ddd
            Please place \b only \b one static assert per line.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// See http://stackoverflow.com/questions/9229601/what-is-in-c-code
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define TCG_STATIC_ASSERT(expr)                      \
Toshihiro Shimizu 890ddd
	struct TCG_JOIN(_tcg_static_assert_, __LINE__) { \
Toshihiro Shimizu 890ddd
		int : -int(!(expr));                         \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \def      TCG_DEBUG(expr)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \brief    Enables the specified expression in case NDEBUG is not defined,
Toshihiro Shimizu 890ddd
            thus binding it to the behavior of the standard assert() macro.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef NDEBUG
Toshihiro Shimizu 890ddd
#define TCG_DEBUG(expr1)
Toshihiro Shimizu 890ddd
#define TCG_DEBUG2(expr1, expr2)
Toshihiro Shimizu 890ddd
#define TCG_DEBUG3(expr1, exrp2, expr3)
Toshihiro Shimizu 890ddd
#define TCG_DEBUG4(expr1, expr2, expr3, expr4)
Toshihiro Shimizu 890ddd
#define TCG_DEBUG5(expr1, expr2, expr3, expr4, expr5)
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define TCG_DEBUG(expr1) expr1
Toshihiro Shimizu 890ddd
#define TCG_DEBUG2(expr1, expr2) expr1, expr2
Toshihiro Shimizu 890ddd
#define TCG_DEBUG3(expr1, exrp2, expr3) expr1, expr2, expr3
Toshihiro Shimizu 890ddd
#define TCG_DEBUG4(expr1, expr2, expr3, expr4) expr1, expr2, expr3, expr4
Toshihiro Shimizu 890ddd
#define TCG_DEBUG5(expr1, expr2, expr3, expr4, expr5) expr1, expr2, expr3, expr4, expr5
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TCG_MACROS_H