HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Assert.h
Go to the documentation of this file.
1 // UT_Assert.h
2 //
3 // Custom portable UT_ASSERT macro
4 //
5 
6 #ifndef UT_ASSERT_H_INCLUDED
7 #define UT_ASSERT_H_INCLUDED
8 
9 #include "UT_API.h"
10 
11 #define UT_ASSERT_LEVEL_NONE 0
12 #define UT_ASSERT_LEVEL_NORMAL 1
13 #define UT_ASSERT_LEVEL_PARANOID 2
14 #define UT_ASSERT_LEVEL_SLOW 3
15 
16 #ifndef UT_ASSERT_LEVEL
17  #define UT_ASSERT_LEVEL UT_ASSERT_LEVEL_NONE
18 #endif
19 
20 // Generates an assertion. Returns TRUE if we should ignore further asserts.
21 UT_API void UT_Assert( const char *file, int linenum, const char *function,
22  const char *condition, const char *reason, int &ignoreflag);
23 
24 // Similar to UT_Assert() but using a variadic format string for the reason.
25 UT_API void UT_AssertFormat( const char *file, int linenum,
26  const char *function, const char *condition, int &ignoreflag,
27  const char *reason_fmt...);
28 
29 
30 // Methods to temporarily disable interactive asserts in specific dangerous
31 // situations.
34 
35 
36 /// Assertions triggered within the lifetime of UT_AssertExceptionScope
37 /// variables will cause UT_AssertException to be thrown instead of the usual
38 /// handling. By default, this is only done when interactive asserts are
39 /// disabled. This class is intended for testing purposes only.
41 {
42 public:
43  UT_AssertExceptionScope(bool when_interactive = true);
45 private:
46  bool myEnabled;
47 };
48 
49 // Exception class thrown when assertions are triggered within an
50 // UT_AssertExceptionScope
52 {
53 public:
54  UT_AssertException(const char *what);
56 
57  const char *what() const noexcept { return myWhat; }
58 
59 private:
60  char *myWhat; // using C string to avoid pulling in UT_String*.h
61 };
62 
63 
64 #if defined(__GNUC__)
65 # define UT_ASSERT_FUNC __PRETTY_FUNCTION__
66 #elif defined(_MSC_VER)
67 # define UT_ASSERT_FUNC __FUNCSIG__
68 #elif defined(__FUNCTION__)
69 # define UT_ASSERT_FUNC __FUNCTION__ "()"
70 #else
71 # define UT_ASSERT_FUNC ((char *)0)
72 #endif
73 
74 #if (UT_ASSERT_LEVEL > UT_ASSERT_LEVEL_NONE)
75  #ifdef UT_INTERNAL_ASSERT
76  #error UT_INTERNAL_UT_ASSERT is already defined!
77  #endif
78  #define UT_INTERNAL_ASSERT(ZZ, ...) \
79  do { \
80  static int ignore = 0; \
81  if( !ignore && !(ZZ) ) \
82  UT_AssertFormat( __FILE__, __LINE__, UT_ASSERT_FUNC, \
83  #ZZ, ignore, __VA_ARGS__); \
84  } while (false)
85  #define UT_INTERNAL_VERIFY(ZZ, ...) \
86  do { \
87  static int ignore = 0; \
88  /* always run ZZ */ \
89  if( !(ZZ) && !ignore ) \
90  UT_AssertFormat( __FILE__, __LINE__, UT_ASSERT_FUNC, \
91  #ZZ, ignore, __VA_ARGS__); \
92  } while (false)
93 
94  #define UT_INTERNAL_VERIFY_RETURN(ZZ, RV) \
95  if (!(ZZ)) \
96  { \
97  static int ignore = 0; \
98  if (!ignore) \
99  UT_Assert( __FILE__, __LINE__, UT_ASSERT_FUNC, #ZZ, 0, \
100  ignore); \
101  return RV; \
102  }
103  #define UT_INTERNAL_ASSERT_EXPR(ZZ,MM) \
104  ((ZZ) ? void(0) : \
105  [&]() { \
106  static int ignore = 0; \
107  if( !ignore ) \
108  UT_Assert( __FILE__, __LINE__, UT_ASSERT_FUNC, #ZZ, MM, \
109  ignore); \
110  }())
111 #endif
112 
113 #ifdef UT_ASSERT_EXPR_P
114  #error UT_ASSERT_EXPR_P is already defined!
115 #endif
116 #ifdef UT_ASSERT_EXPR
117  #error UT_ASSERT_EXPR is already defined!
118 #endif
119 #ifdef UT_ASSERT_SLOW
120  #error UT_ASSERT_SLOW is already defined!
121 #endif
122 #ifdef UT_ASSERT_P
123  #error UT_ASSERT_P is already defined!
124 #endif
125 #ifdef UT_ASSERT
126  #error UT_ASSERT is already defined!
127 #endif
128 #ifdef UT_ASSERT_MSG_SLOW
129  #error UT_ASSERT_MSG_SLOW is already defined!
130 #endif
131 #ifdef UT_ASSERT_MSG_P
132  #error UT_ASSERT_MSG_P is already defined!
133 #endif
134 #ifdef UT_ASSERT_MSG
135  #error UT_ASSERT_MSG is already defined!
136 #endif
137 
138 // do these in descending order:
139 #if (UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_SLOW)
140  #define UT_ASSERT_EXPR_P(ZZ) UT_INTERNAL_ASSERT_EXPR(ZZ, 0)
141  #define UT_ASSERT_EXPR(ZZ) UT_INTERNAL_ASSERT_EXPR(ZZ, 0)
142  #define UT_ASSERT_SLOW(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
143  #define UT_ASSERT_P(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
144  #define UT_ASSERT(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
145  #define UT_ASSERT_MSG_SLOW(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
146  #define UT_ASSERT_MSG_P(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
147  #define UT_ASSERT_MSG(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
148 #elif (UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_PARANOID)
149  #define UT_ASSERT_EXPR_P(ZZ) UT_INTERNAL_ASSERT_EXPR(ZZ, 0)
150  #define UT_ASSERT_EXPR(ZZ) UT_INTERNAL_ASSERT_EXPR(ZZ, 0)
151  #define UT_ASSERT_SLOW(ZZ) ((void)0)
152  #define UT_ASSERT_P(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
153  #define UT_ASSERT(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
154  #define UT_ASSERT_MSG_SLOW(ZZ, ...) ((void)0)
155  #define UT_ASSERT_MSG_P(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
156  #define UT_ASSERT_MSG(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
157 #elif (UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NORMAL)
158  #define UT_ASSERT_EXPR_P(ZZ) ((void)0)
159  #define UT_ASSERT_EXPR(ZZ) UT_INTERNAL_ASSERT_EXPR(ZZ, 0)
160  #define UT_ASSERT_SLOW(ZZ) ((void)0)
161  #define UT_ASSERT_P(ZZ) ((void)0)
162  #define UT_ASSERT(ZZ) UT_INTERNAL_ASSERT(ZZ, 0)
163  #define UT_ASSERT_MSG_SLOW(ZZ, ...) ((void)0)
164  #define UT_ASSERT_MSG_P(ZZ, ...) ((void)0)
165  #define UT_ASSERT_MSG(ZZ, ...) UT_INTERNAL_ASSERT(ZZ, __VA_ARGS__)
166 #else // if (UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NONE)
167  #define UT_ASSERT_EXPR_P(ZZ) ((void)0)
168  #define UT_ASSERT_EXPR(ZZ) ((void)0)
169  #define UT_ASSERT_SLOW(ZZ) ((void)0)
170  #define UT_ASSERT_P(ZZ) ((void)0)
171  #define UT_ASSERT(ZZ) ((void)0)
172  #define UT_ASSERT_MSG_SLOW(ZZ, ...) ((void)0)
173  #define UT_ASSERT_MSG_P(ZZ, ...) ((void)0)
174  #define UT_ASSERT_MSG(ZZ, ...) ((void)0)
175 #endif
176 
177 #include <SYS/SYS_StaticAssert.h>
178 #define UT_ASSERT_COMPILETIME(expr) SYS_STATIC_ASSERT(expr)
179 
180 // This macro allows you to enable a block of code only
181 // when UT_ASSERT is enabled. This will help clean up
182 // "unreferenced variables" in the case where you have variables that
183 // are only referenced in asserts.
184 
185 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NORMAL
186 #define UT_IF_ASSERT(ZZ) ZZ
187 #define UT_IFNOT_ASSERT(ZZ)
188 #else
189 #define UT_IF_ASSERT(ZZ)
190 #define UT_IFNOT_ASSERT(ZZ) ZZ
191 #endif
192 
193 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_PARANOID
194 #define UT_IF_ASSERT_P(ZZ) ZZ
195 #define UT_IFNOT_ASSERT_P(ZZ)
196 #else
197 #define UT_IF_ASSERT_P(ZZ)
198 #define UT_IFNOT_ASSERT_P(ZZ) ZZ
199 #endif
200 
201 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_SLOW
202 #define UT_IF_ASSERT_SLOW(ZZ) ZZ
203 #define UT_IFNOT_ASSERT_SLOW(ZZ)
204 #else
205 #define UT_IF_ASSERT_SLOW(ZZ)
206 #define UT_IFNOT_ASSERT_SLOW(ZZ) ZZ
207 #endif
208 
209 // When asserts are enabled, UT_VERIFY() will trigger an assert if the expr
210 // is false. When asserts are disabled, the expr is still evaluated.
211 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_NORMAL
212  #define UT_VERIFY(expr) UT_INTERNAL_VERIFY(expr, 0)
213  #define UT_VERIFY_MSG(expr, ...) UT_INTERNAL_VERIFY(expr, __VA_ARGS__)
214  #define UT_VERIFY_RETURN(ZZ, RV) UT_INTERNAL_VERIFY_RETURN(ZZ, RV)
215  #define UT_VERIFY_RETURN_VOID(ZZ) UT_INTERNAL_VERIFY_RETURN(ZZ,)
216 #else
217  #define UT_VERIFY(expr) ((void)(expr))
218  #define UT_VERIFY_MSG(expr, ...) ((void)(expr))
219  #define UT_VERIFY_RETURN(ZZ, RV) if (!(ZZ)) { return RV; }
220  #define UT_VERIFY_RETURN_VOID(ZZ) if (!(ZZ)) { return; }
221 #endif
222 #if UT_ASSERT_LEVEL >= UT_ASSERT_LEVEL_PARANOID
223  #define UT_VERIFY_P(expr) UT_INTERNAL_VERIFY(expr, 0)
224 #else
225  #define UT_VERIFY_P(expr) ((void)(expr))
226 #endif
227 
229 {
235 };
236 
237 /// UTverify_cast performs a static_cast, but when paranoid assertions are
238 /// enabled it will also perform a dynamic cast to verify the cast is valid.
239 /// UT_ASSERT_P() is used instead of UT_ASSERT() to avoid overhead in normal
240 /// development builds.
241 #include <SYS/SYS_Inline.h>
242 template <typename TO_T, typename FROM_T>
243 SYS_FORCE_INLINE TO_T
244 UTverify_cast(FROM_T from)
245 {
246  UT_ASSERT_P(dynamic_cast<TO_T>(from) == from && "Invalid static cast");
247  return static_cast<TO_T>(from);
248 }
249 
250 /// UTsubclassResponsibility raises an assertion indicating that a subclass has
251 /// not implemented an inherited method. This should only be called from a
252 /// base class method that is not expected to run.
253 UT_API void UTsubclassResponsibility(const char *classname, const char *member);
254 
255 #endif // UT_ASSERT_H_INCLUDED
UT_AssertResponse
Definition: UT_Assert.h:228
#define UT_API
Definition: UT_API.h:14
SYS_FORCE_INLINE TO_T UTverify_cast(FROM_T from)
Definition: UT_Assert.h:244
UT_API void UTsubclassResponsibility(const char *classname, const char *member)
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:170
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
UT_API void UTdisableInteractiveAssertsOff()
const char * what() const noexcept
Definition: UT_Assert.h:57
GLenum condition
Definition: glew.h:13027
#define const
Definition: zconf.h:214
UT_API void UT_Assert(const char *file, int linenum, const char *function, const char *condition, const char *reason, int &ignoreflag)
UT_API void UT_AssertFormat(const char *file, int linenum, const char *function, const char *condition, int &ignoreflag, const char *reason_fmt...)
UT_API void UTdisableInteractiveAssertsOn()