src/Utility/PAssert.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef PASSERT_H
00012 #define PASSERT_H
00013 
00015 //
00016 // This is a compile time assert.
00017 // That is, if you say:
00018 //   CTAssert<true>::test();
00019 // it compiles just fine and inserts no code.
00020 // If you say:
00021 //   CTAssert<false>::test();
00022 // you get a compile error that it can't find CTAssert<false>::test().
00023 //
00024 // The template argument can of course be a calculation of const bools
00025 // that are known at compile time.
00026 //
00028 
00029 template<bool B> struct IpplCTAssert {};
00030 
00031 template<> struct IpplCTAssert<true> { static void test() {} };
00032 
00033 #if defined(NOCTAssert)
00034 #define CTAssert(c)
00035 #else
00036 #define CTAssert(c) IpplCTAssert<(c)>::test()
00037 #endif
00038 
00039 //===========================================================================//
00040 // class assertion - exception notification class for assertions
00041 
00042 // This class should really be derived from std::runtime_error, but
00043 // unfortunately we don't have good implementation of the library standard
00044 // yet, on compilers other than KCC.  So, this class will keep with the
00045 // "what" method evidenced in the standard, but dispense with inheriting from
00046 // classes for which we don't have implementations...
00047 //===========================================================================//
00048 
00049 class assertion /* : std::runtime_error */
00050 {
00051     char *msg;
00052   public:
00053     assertion( const char *cond, const char *file, int line );
00054     assertion( const char *m );
00055     assertion( const assertion& a );
00056     ~assertion() { delete[] msg; }
00057     assertion& operator=( const assertion& a );
00058     const char* what() const { return msg; }
00059 };
00060 
00061 //---------------------------------------------------------------------------//
00062 // Now we define a run time assertion mechanism.  We will call it "PAssert",
00063 // to reflect the idea that this is for use in IPPL per se, recognizing that
00064 // there are numerous other assertion facilities in use in client codes.
00065 //---------------------------------------------------------------------------//
00066 
00067 // These are the functions that will be called in the assert macros.
00068 
00069 void toss_cookies( const char *cond, const char *file, int line );
00070 void insist( const char *cond, const char *msg, const char *file, int line );
00071 
00072 //---------------------------------------------------------------------------//
00073 // The PAssert macro is intended to be used for validating preconditions
00074 // which must be true in order for following code to be correct, etc.  For
00075 // example, PAssert( x > 0. ); y = sqrt(x);  If the assertion fails, the code
00076 // should just bomb.  Philosophically, it should be used to feret out bugs in
00077 // preceding code, making sure that prior results are within reasonable
00078 // bounds before proceeding to use those results in further computation, etc.
00079 //---------------------------------------------------------------------------//
00080 
00081 #ifdef NOPAssert
00082 #define PAssert(c) 
00083 #else
00084 #define PAssert(c) if (!(c)) toss_cookies( #c, __FILE__, __LINE__ );
00085 #endif
00086 
00087 //---------------------------------------------------------------------------//
00088 // The PInsist macro is akin to the PAssert macro, but it provides the
00089 // opportunity to specify an instructive message.  The idea here is that you
00090 // should use Insist for checking things which are more or less under user
00091 // control.  If the user makes a poor choice, we "insist" that it be
00092 // corrected, providing a corrective hint.
00093 //---------------------------------------------------------------------------//
00094 
00095 #define PInsist(c,m) if (!(c)) insist( #c, m, __FILE__, __LINE__ );
00096 
00097 //---------------------------------------------------------------------------//
00098 // NOTE:  We provide a way to eliminate assertions, but not insistings.  The
00099 // idea is that PAssert is used to perform sanity checks during program
00100 // development, which you might want to eliminate during production runs for
00101 // performance sake.  PInsist is used for things which really really must be
00102 // true, such as "the file must've been opened", etc.  So, use PAssert for
00103 // things which you want taken out of production codes (like, the check might
00104 // inhibit inlining or something like that), but use PInsist for those things
00105 // you want checked even in a production code.
00106 //---------------------------------------------------------------------------//
00107 
00108 #endif // PASSERT_H
00109 
00110 /***************************************************************************
00111  * $RCSfile: PAssert.h,v $   $Author: adelmann $
00112  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00113  * IPPL_VERSION_ID: $Id: PAssert.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00114  ***************************************************************************/

Generated on Mon Jan 16 13:23:59 2006 for IPPL by  doxygen 1.4.6