OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PAssert.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef PASSERT_H
12 #define PASSERT_H
13 #include "Utility/IpplInfo.h"
14 
15 #include <exception>
16 #include <stdexcept>
17 #include <string>
19 //
20 // This is a compile time assert.
21 // That is, if you say:
22 // CTAssert<true>::test();
23 // it compiles just fine and inserts no code.
24 // If you say:
25 // CTAssert<false>::test();
26 // you get a compile error that it can't find CTAssert<false>::test().
27 //
28 // The template argument can of course be a calculation of const bools
29 // that are known at compile time.
30 //
32 
33 template<bool B> struct IpplCTAssert {};
34 
35 template<> struct IpplCTAssert<true> { static void test() {} };
36 
37 #if defined(NOCTAssert)
38 #define CTAssert(c)
39 #else
40 #define CTAssert(c) IpplCTAssert<(c)>::test()
41 #endif
42 
43 //===========================================================================//
44 // class assertion - exception notification class for assertions
45 
46 // This class should really be derived from std::runtime_error, but
47 // unfortunately we don't have good implementation of the library standard
48 // yet, on compilers other than KCC. So, this class will keep with the
49 // "what" method evidenced in the standard, but dispense with inheriting from
50 // classes for which we don't have implementations...
51 //===========================================================================//
52 
53 class assertion: public std::runtime_error
54 {
55  char *msg;
56 public:
57  assertion( const char *cond, const char *file, int line );
58  assertion( const char *m );
59  assertion( const assertion& a );
60  ~assertion() throw() { delete[] msg; }
61  assertion& operator=( const assertion& a );
62 #if defined(__clang__)
63 #pragma clang diagnostic push
64 #pragma clang diagnostic ignored "-Woverloaded-virtual"
65 #endif
66  const char* what() { return msg; }
67 #if defined(__clang__)
68 #pragma clang diagnostic pop
69 #endif
70 
71 };
72 
73 //---------------------------------------------------------------------------//
74 // Now we define a run time assertion mechanism. We will call it "PAssert",
75 // to reflect the idea that this is for use in IPPL per se, recognizing that
76 // there are numerous other assertion facilities in use in client codes.
77 //---------------------------------------------------------------------------//
78 
79 // These are the functions that will be called in the assert macros.
80 
81 void toss_cookies( const char *cond, const char *file, int line );
82 template <class S, class T>
83 void toss_cookies( const char *cond, const char *astr, const char *bstr, S a, T b, const char *file, int line) {
84 
85  //Ippl::exitAllNodes(cond, false);
86 
87  std::string what = "Assertion '" + std::string(cond) + "' failed. \n";
88  what += std::string(astr) + " = " + std::to_string(a) + ", ";
89  what += std::string(bstr) + " = " + std::to_string(b) + "\n";
90  what += "in \n";
91  what += std::string(file) + ", line " + std::to_string(line);
92 
93  throw std::runtime_error(what);
94 }
95 
96 
97 void insist( const char *cond, const char *msg, const char *file, int line );
98 
99 //---------------------------------------------------------------------------//
100 // The PAssert macro is intended to be used for validating preconditions
101 // which must be true in order for following code to be correct, etc. For
102 // example, PAssert( x > 0. ); y = sqrt(x); If the assertion fails, the code
103 // should just bomb. Philosophically, it should be used to feret out bugs in
104 // preceding code, making sure that prior results are within reasonable
105 // bounds before proceeding to use those results in further computation, etc.
106 //---------------------------------------------------------------------------//
107 
108 #ifdef NOPAssert
109 #define PAssert(c)
110 #define PAssert_EQ(a, b)
111 #define PAssert_NE(a, b)
112 #define PAssert_LT(a, b)
113 #define PAssert_LE(a, b)
114 #define PAssert_GT(a, b)
115 #define PAssert_GE(a, b)
116 #else
117 #define PAssert(c) if (!(c)) toss_cookies( #c, __FILE__, __LINE__ );
118 #define PAssert_CMP(cmp, a, b) if (!(cmp)) toss_cookies(#cmp, #a, #b, a, b, __FILE__, __LINE__);
119 #define PAssert_EQ(a, b) PAssert_CMP(a == b, a, b)
120 #define PAssert_NE(a, b) PAssert_CMP(a != b, a, b)
121 #define PAssert_LT(a, b) PAssert_CMP(a < b, a, b)
122 #define PAssert_LE(a, b) PAssert_CMP(a <= b, a, b)
123 #define PAssert_GT(a, b) PAssert_CMP(a > b, a, b)
124 #define PAssert_GE(a, b) PAssert_CMP(a >= b, a, b)
125 #endif
126 
127 //---------------------------------------------------------------------------//
128 // The PInsist macro is akin to the PAssert macro, but it provides the
129 // opportunity to specify an instructive message. The idea here is that you
130 // should use Insist for checking things which are more or less under user
131 // control. If the user makes a poor choice, we "insist" that it be
132 // corrected, providing a corrective hint.
133 //---------------------------------------------------------------------------//
134 
135 #define PInsist(c,m) if (!(c)) insist( #c, m, __FILE__, __LINE__ );
136 
137 //---------------------------------------------------------------------------//
138 // NOTE: We provide a way to eliminate assertions, but not insistings. The
139 // idea is that PAssert is used to perform sanity checks during program
140 // development, which you might want to eliminate during production runs for
141 // performance sake. PInsist is used for things which really really must be
142 // true, such as "the file must've been opened", etc. So, use PAssert for
143 // things which you want taken out of production codes (like, the check might
144 // inhibit inlining or something like that), but use PInsist for those things
145 // you want checked even in a production code.
146 //---------------------------------------------------------------------------//
147 
148 #endif // PASSERT_H
149 
150 /***************************************************************************
151  * $RCSfile: PAssert.h,v $ $Author: adelmann $
152  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:33 $
153  * IPPL_VERSION_ID: $Id: PAssert.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $
154  ***************************************************************************/
assertion(const char *cond, const char *file, int line)
Definition: PAssert.cpp:45
static void test()
Definition: PAssert.h:35
void insist(const char *cond, const char *msg, const char *file, int line)
Definition: PAssert.cpp:93
Definition: rbendmap.h:8
assertion & operator=(const assertion &a)
Definition: PAssert.cpp:67
const char * what()
Definition: PAssert.h:66
~assertion()
Definition: PAssert.h:60
char * msg
Definition: PAssert.h:55
void toss_cookies(const char *cond, const char *file, int line)
Definition: PAssert.cpp:78