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