/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Support for checking type signatures.
 * @verbatim
 *
 * Type signatures are used to catch pointers to objects of the wrong type
 * and to ensure the memory holding object isn't corrupted.
 * Type signatures are conditionally compiled according to #define COMPILE_TYPESIGS.
 * A set of macros are provided which expand to nothing if COMPILE_TYPESIGS=0.
 * Secondary (and additional) type signatures can be used to for checking
 * the base class type signature of derived object.
 *
 * Passing the wrong type signature by mistake will be caught by the compiler
 * as the name of the type signature member is catenated with the name of
 * the enum (this is a macro trick).
 *
 * Example:
 *
 *     // Example of declaring type signature enums.
 *     enum
 *     {
 *        TYPESIG_INVALID,
 *        TYPESIG_MYCLASS,
 *     };
 *
 *     // Example of declaring and setting a type signature in a class.
 *     // The destructor invalidates the type signature in order to
 *     // catch the error of using a destroyed object by a stale pointer.
 *     class MyClass
 *     {
 *     public:
 *         MyClass()        { SET_TYPESIG(this,TYPESIG_MYCLASS); valid = false; }
 *         MyClass( int x ) { SET_TYPESIG(this,TYPESIG_MYCLASS); valid = true; value = x; }
 *         ~MyClass()       { INVALIDATE_TYPESIG(this,TYPESIG_MYCLASS); }
 *         bool valid;
 *         int  value;
 *         DECLARE_TYPESIG(TYPESIG_MYCLASS) // declare last for better alignment and if cast
 *     }
 *
 *     // DECLARE_TYPESIG_AUTO() is a shorthand that expands a constructor
 *     // and destructor to automatically set the type signature.
 *     // Using it in POD structs is recommended but may be inappropriate in complex classes.
 *     struct Pod  // Plain Old Data
 *     {
 *         int   data;
 *         DECLARE_TYPESIG_AUTO(Pod,TYPESIG_POD)  // !!!DECLARE LAST IN CASE OF CASTING!!!
 *     };
 *
 *     // Example of checking a type signature.
 *     // NOTE: For terseness, CHECK_TYPESIG() asserts that the pointer isn't NULL
 *     //       to obviate writing ASSERT(p) prior to CHECK_TYPESIG(p,TYPESIG_MYSTRUCT).
 *     //       If a pointer is allowed to be NULL, use CHECK_TYPESIG_NULL_OK() instead.
 *     void Do( Pod* pod )
 *     {
 *         CHECK_TYPESIG(pod,TYPESIG_POD);         // asserts pointer != NULL
 *         CHECK_TYPESIG_NULL_OK(pod,TYPESIG_POD); // alternative that allows NULL
 *     }
 *
 * @endverbatim
 *//*
 * LEGAL:   COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/
