IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
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#include <exception>
10#include <stdexcept>
11#include <string>
12
13#include "Utility/IpplInfo.h"
15//
16// This is a compile time assert.
17// That is, if you say:
18// CTAssert<true>::test();
19// it compiles just fine and inserts no code.
20// If you say:
21// CTAssert<false>::test();
22// you get a compile error that it can't find CTAssert<false>::test().
23//
24// The template argument can of course be a calculation of const bools
25// that are known at compile time.
26//
28
29template <bool B>
30struct IpplCTAssert {};
31
32template <>
33struct IpplCTAssert<true> {
34 static void test() {}
35};
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
53class assertion : public std::runtime_error {
54 char* msg;
55
56public:
57 assertion(const char* cond, const char* file, int line);
58
59 assertion(const char* m);
60
61 assertion(const assertion& a);
62
63 ~assertion() throw() { delete[] msg; }
64
65 assertion& operator=(const assertion& a);
66
67 using std::runtime_error::what;
68
69 virtual const char* what() { return msg; };
70};
71
72//---------------------------------------------------------------------------//
73// Now we define a run time assertion mechanism. We will call it "PAssert",
74// to reflect the idea that this is for use in IPPL per se, recognizing that
75// there are numerous other assertion facilities in use in client codes.
76//---------------------------------------------------------------------------//
77
78// These are the functions that will be called in the assert macros.
79void toss_cookies(const char* cond, const char* file, int line);
80template <class S, class T>
81void toss_cookies(const char* cond, const char* astr, const char* bstr, S a, T b, const char* file,
82 int line) {
83 std::string what = "Assertion '" + std::string(cond) + "' failed. \n";
84 what += std::string(astr) + " = " + std::to_string(a) + ", ";
85 what += std::string(bstr) + " = " + std::to_string(b) + "\n";
86 what += "in \n";
87 what += std::string(file) + ", line " + std::to_string(line);
88
89 throw std::runtime_error(what);
90}
91void insist(const char* cond, const char* msg, const char* file, int line);
92
93//---------------------------------------------------------------------------//
94// The PAssert macro is intended to be used for validating preconditions
95// which must be true in order for following code to be correct, etc. For
96// example, PAssert( x > 0. ); y = sqrt(x); If the assertion fails, the code
97// should just bomb. Philosophically, it should be used to feret out bugs in
98// preceding code, making sure that prior results are within reasonable
99// bounds before proceeding to use those results in further computation, etc.
100//---------------------------------------------------------------------------//
101
102#ifdef NOPAssert
103#define PAssert(c)
104#define PAssert_EQ(a, b)
105#define PAssert_NE(a, b)
106#define PAssert_LT(a, b)
107#define PAssert_LE(a, b)
108#define PAssert_GT(a, b)
109#define PAssert_GE(a, b)
110#else
111#if defined(__HIP_PLATFORM_AMD__) \
112 || defined(__CUDA_ARCH__) // toss_cookies are not supported so just do a no-operation
113#define PAssert(c)
114#define PAssert_CMP(cmp, a, b)
115#else
116#define PAssert(c) \
117 if (!(c)) \
118 toss_cookies(#c, __FILE__, __LINE__);
119#define PAssert_CMP(cmp, a, b) \
120 if (!(cmp)) \
121 toss_cookies(#cmp, #a, #b, a, b, __FILE__, __LINE__);
122#endif
123#define PAssert_EQ(a, b) PAssert_CMP(a == b, a, b)
124#define PAssert_NE(a, b) PAssert_CMP(a != b, a, b)
125#define PAssert_LT(a, b) PAssert_CMP(a < b, a, b)
126#define PAssert_LE(a, b) PAssert_CMP(a <= b, a, b)
127#define PAssert_GT(a, b) PAssert_CMP(a > b, a, b)
128#define PAssert_GE(a, b) PAssert_CMP(a >= b, a, b)
129#endif
130
131//---------------------------------------------------------------------------//
132// The PInsist macro is akin to the PAssert macro, but it provides the
133// opportunity to specify an instructive message. The idea here is that you
134// should use Insist for checking things which are more or less under user
135// control. If the user makes a poor choice, we "insist" that it be
136// corrected, providing a corrective hint.
137//---------------------------------------------------------------------------//
138
139#define PInsist(c, m) \
140 if (!(c)) \
141 insist(#c, m, __FILE__, __LINE__);
142
143//---------------------------------------------------------------------------//
144// NOTE: We provide a way to eliminate assertions, but not insistings. The
145// idea is that PAssert is used to perform sanity checks during program
146// development, which you might want to eliminate during production runs for
147// performance sake. PInsist is used for things which really really must be
148// true, such as "the file must've been opened", etc. So, use PAssert for
149// things which you want taken out of production codes (like, the check might
150// inhibit inlining or something like that), but use PInsist for those things
151// you want checked even in a production code.
152//---------------------------------------------------------------------------//
153
154#endif // PASSERT_H
155
156// vi: set et ts=4 sw=4 sts=4:
157// Local Variables:
158// mode:c
159// c-basic-offset: 4
160// indent-tabs-mode: nil
161// require-final-newline: nil
162// End:
void insist(const char *cond, const char *msg, const char *file, int line)
Definition PAssert.cpp:84
void toss_cookies(const char *cond, const char *file, int line)
Definition PAssert.cpp:73
static void test()
Definition PAssert.h:34
assertion & operator=(const assertion &a)
Definition PAssert.cpp:63
assertion(const char *cond, const char *file, int line)
Definition PAssert.cpp:45
char * msg
Definition PAssert.h:54
virtual const char * what()
Definition PAssert.h:69
~assertion()
Definition PAssert.h:63