Vault  4.1
vassert.h
Go to the documentation of this file.
00001 /*
00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved.
00003 This file is part of the Code Vault version 4.1
00004 http://www.bombaydigital.com/
00005 License: MIT. See LICENSE.md in the Vault top level directory.
00006 */
00007 
00008 #ifndef vassert_h
00009 #define vassert_h
00010 
00013 #include "vtypes.h"
00014 
00015 #include "vstring.h"
00016 #include "vcodepoint.h"
00017 #include "vchar.h"
00018 #include "vinstant.h"
00019 #include "vcolor.h"
00020 
00021 /*
00022 These macros log an error and throw a VStackTraceException containing a stack crawl if the assertion fails.
00023 
00024 Note: the "do { ... } while (false)" macro syntax is the preferred way to ensure proper expansion regardless
00025 of caller's conditional branching syntax.
00026 
00027 We separate out the testing of the assertion from the processing of the assertion failure so that the label
00028 supplied to the macro does not have to be evaluated in the success case. For example, a complicated string
00029 formatting operation to form the label will have no overhead until actual use in a failed assertion.
00030 
00031 Usage Notes
00032 
00033 The preprocessor symbol V_ASSERT_ENABLED determines whether the macros do anything at all.
00034 By default it is on if V_DEBUG is on. Normally this means for debug builds.
00035 However, if you #define V_ASSERT_ENABLED 1 then it will be on all the time. This is actually recommended.
00036 
00037 The preprocessor symbol VAULT_THROW_ON_ASSERTION_FAILURE determines whether a failed assertion
00038 throws a stack trace exception in addition to logging an error.
00039 
00040 You can assert any boolean condition with the VASSERT() macro. However, the more specific macros will yield
00041 more informative output when the assertion fails. For example, compare the output on failure of these two
00042 similar tests:
00043 
00044 VASSERT(nameOfOwner == nameOfParticipant);
00045   Assertion failed: nameOfOwner == nameOfParticipant
00046 
00047 VASSERT_EQUAL(nameOfOwner, nameOfParticipant);
00048   Equal assertion failed. (nameOfOwner = Flavio) (nameOfParticipant = Fernando)
00049 
00050 You can use VASSERT_VALUE if you have a complex boolean to evaluate and want to supply a value string or other
00051 information to be included if the assertion fails, for example:
00052 VASSERT_VALUE(x == 1 || x == 20 || x > 50, x, VSTRING_INT(x));
00053   Assertion failed: x == 1 || x == 20 || x > 50 (x = 42)
00054 Arg 1 is the boolean expression to test.
00055 Arg 2 gets stringified to form the label. (x)
00056 Arg 3 is a string used for the value. (42)
00057 
00058 Another example, with good/better/best output:
00059 
00060 VASSERT(balance < 100);
00061   Assertion failed: balance < 100
00062 
00063 VASSERT_LESS_THAN(balance, 100);
00064   Less Than assertion failed. (balance = 250) (100 = 100)
00065 
00066 VASSERT_LESS_THAN(balance, MAX_BALANCE);
00067   Less Than assertion failed. (balance = 250) (MAX_BALANCE = 100)
00068 
00069 */
00070 
00071 #ifdef V_ASSERT_ACTIVE
00072     #define VASSERT(expression)                             do { if (!(expression))                     VAssert::failedAssert(#expression, __FILE__, __LINE__); } while (false)
00073     #define VASSERT_VALUE(expression, valName, valString)   do { if (!(expression))                     VAssert::failedAssertValue(#expression, #valName, valString, __FILE__, __LINE__); } while (false)
00074     #define VASSERT_NULL(pointer)                           do { if (pointer != NULL)                   VAssert::failedAssertNull(pointer, #pointer, __FILE__, __LINE__); } while (false)
00075     #define VASSERT_NOT_NULL(pointer)                       do { if (pointer == NULL)                   VAssert::failedAssertNotNull(#pointer, __FILE__, __LINE__); } while (false)
00076     #define VASSERT_ZERO(i)                                 do { if (i != 0)                            VAssert::failedAssertZero((Vs64)i, #i, __FILE__, __LINE__); } while (false)
00077     #define VASSERT_NON_ZERO(i)                             do { if (i == 0)                            VAssert::failedAssertNonZero(#i, __FILE__, __LINE__); } while (false)
00078     #define VASSERT_EQUAL(a, b)                             do { if (a != b)                            VAssert::failedAssertEqual(a, b, #a, #b, __FILE__, __LINE__); } while (false)
00079     #define VASSERT_NOT_EQUAL(a, b)                         do { if (a == b)                            VAssert::failedAssertNotEqual(a, #a, #b, __FILE__, __LINE__); } while (false)
00080     #define VASSERT_LESS_THAN(a, b)                         do { if (!(a < b))                          VAssert::failedLessGreaterComparison(true, false, a, b, #a, #b, __FILE__, __LINE__); } while (false)
00081     #define VASSERT_LESS_THAN_OR_EQUAL(a, b)                do { if (!(a <= b))                         VAssert::failedLessGreaterComparison(true, true, a, b, #a, #b, __FILE__, __LINE__); } while (false)
00082     #define VASSERT_GREATER_THAN(a, b)                      do { if (!(a > b))                          VAssert::failedLessGreaterComparison(false, false, a, b, #a, #b, __FILE__, __LINE__); } while (false)
00083     #define VASSERT_GREATER_THAN_OR_EQUAL(a, b)             do { if (!(a >= b))                         VAssert::failedLessGreaterComparison(false, true, a, b, #a, #b, __FILE__, __LINE__); } while (false)
00084     #define VASSERT_IN_RANGE(i, minVal, maxVal)             do { if (!((i >= minVal) && (i <= maxVal))) VAssert::failedRangeCheck(i, minVal, maxVal, #i, #minVal, #maxVal, __FILE__, __LINE__); } while (false)
00085 #else
00086     #define VASSERT(expression)                             ((void) 0)
00087     #define VASSERT_VALUE(expression, valName, valString)   ((void) 0)
00088     #define VASSERT_NULL(pointer)                           ((void) 0)
00089     #define VASSERT_NOT_NULL(pointer)                       ((void) 0)
00090     #define VASSERT_ZERO(i)                                 ((void) 0)
00091     #define VASSERT_NON_ZERO(i)                             ((void) 0)
00092     #define VASSERT_EQUAL(a, b)                             ((void) 0)
00093     #define VASSERT_NOT_EQUAL(a, b)                         ((void) 0)
00094     #define VASSERT_LESS_THAN(a, b)                         ((void) 0)
00095     #define VASSERT_LESS_THAN_OR_EQUAL(a, b)                ((void) 0)
00096     #define VASSERT_GREATER_THAN(a, b)                      ((void) 0)
00097     #define VASSERT_GREATER_THAN_OR_EQUAL(a, b)             ((void) 0)
00098     #define VASSERT_IN_RANGE(i, minVal, maxVal)             ((void) 0)
00099 #endif
00100 
00105 class VAssert {
00106     public:
00107 
00108         // Note: The reason that 'expressions' are passed as raw (const char*) rather than (const VString&) is that they are always formed
00109         // by the # stringifier from one of the macros defined above, are therefore compile-time constants, and constructing a VString to wrap
00110         // each of them as we pass them along to the string formatter would be needlessly wasteful.
00111 
00112         // For convenience, each numeric non-int version of failedAssertEqual(), failedLessGreaterComparison(), and failedRangeCheck() has
00113         // an alternate where the values other than a are declared as int. This allows you to assert a non-int variable to be some int value,
00114         // e.g. VASSERT_EQUAL(x, 5) where x is not an int. Otherwise, you'd have to carefully cast int constants to particular types.
00115 
00116         static void failedAssert(const char* expression, const char* file, int line);
00117         static void failedAssertValue(const char* expression, const char* valName, const VString& valString, const char* file, int line);
00118         static void failedAssertNull(const void* p, const char* expression, const char* file, int line);
00119         static void failedAssertNotNull(const char* expression, const char* file, int line);
00120         static void failedAssertZero(Vs64 i, const char* expression, const char* file, int line); // we always upcast to Vs64
00121         static void failedAssertNonZero(const char* expression, const char* file, int line);
00122 
00123         static void failedAssertEqual(int a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00124         static void failedAssertEqual(unsigned int a, unsigned int b,           const char* expressionA, const char* expressionB, const char* file, int line);
00125         static void failedAssertEqual(unsigned int a, int b,                    const char* expressionA, const char* expressionB, const char* file, int line);
00126         static void failedAssertEqual(const void* a, const void* b,             const char* expressionA, const char* expressionB, const char* file, int line);
00127         static void failedAssertEqual(bool a, bool b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00128         static void failedAssertEqual(Vs8 a, Vs8 b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00129         static void failedAssertEqual(Vs8 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00130         static void failedAssertEqual(Vu8 a, Vu8 b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00131         static void failedAssertEqual(Vu8 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00132         static void failedAssertEqual(Vs16 a, Vs16 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00133         static void failedAssertEqual(Vs16 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00134         static void failedAssertEqual(Vu16 a, Vu16 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00135         static void failedAssertEqual(Vu16 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00136 
00137 #ifndef Vx32_IS_xINT /* don't redefine if types are same */
00138         static void failedAssertEqual(Vs32 a, Vs32 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00139         static void failedAssertEqual(Vs32 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00140         static void failedAssertEqual(Vu32 a, Vu32 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00141         static void failedAssertEqual(Vu32 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00142 #endif /* not Vx32_IS_xINT */
00143 
00144 #ifndef Vx64_IS_xINT /* don't redefine if types are same */
00145         static void failedAssertEqual(Vs64 a, Vs64 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00146         static void failedAssertEqual(Vs64 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00147         static void failedAssertEqual(Vu64 a, Vu64 b,                           const char* expressionA, const char* expressionB, const char* file, int line);
00148         static void failedAssertEqual(Vu64 a, int b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00149 #endif /* not Vx64_IS_xINT */
00150 
00151         static void failedAssertEqual(VDouble a, VDouble b,                     const char* expressionA, const char* expressionB, const char* file, int line);
00152         static void failedAssertEqual(const VString& a, const VString& b,       const char* expressionA, const char* expressionB, const char* file, int line);
00153         static void failedAssertEqual(const VString& a, const char* b,          const char* expressionA, const char* expressionB, const char* file, int line);
00154         static void failedAssertEqual(const char* a, const VString& b,          const char* expressionA, const char* expressionB, const char* file, int line);
00155         static void failedAssertEqual(const VCodePoint& a, const VCodePoint& b, const char* expressionA, const char* expressionB, const char* file, int line);
00156         static void failedAssertEqual(const VChar& a, const VChar& b,           const char* expressionA, const char* expressionB, const char* file, int line);
00157         static void failedAssertEqual(const VChar& a, char b,                   const char* expressionA, const char* expressionB, const char* file, int line);
00158         static void failedAssertEqual(const VDuration& a, const VDuration& b,   const char* expressionA, const char* expressionB, const char* file, int line);
00159         static void failedAssertEqual(const VInstant& a, const VInstant& b,     const char* expressionA, const char* expressionB, const char* file, int line);
00160         static void failedAssertEqual(const VColor& a, const VColor& b,         const char* expressionA, const char* expressionB, const char* file, int line);
00161         static void failedAssertEqual(const VColorPair& a, const VColorPair& b, const char* expressionA, const char* expressionB, const char* file, int line);
00162 
00163         static void failedAssertNotEqual(int val,               const char* expressionA, const char* expressionB, const char* file, int line);
00164         static void failedAssertNotEqual(unsigned int val,      const char* expressionA, const char* expressionB, const char* file, int line);
00165         static void failedAssertNotEqual(const void* val,       const char* expressionA, const char* expressionB, const char* file, int line);
00166         static void failedAssertNotEqual(bool val,              const char* expressionA, const char* expressionB, const char* file, int line);
00167         static void failedAssertNotEqual(Vs8 val,               const char* expressionA, const char* expressionB, const char* file, int line);
00168         static void failedAssertNotEqual(Vu8 val,               const char* expressionA, const char* expressionB, const char* file, int line);
00169         static void failedAssertNotEqual(Vs16 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00170         static void failedAssertNotEqual(Vu16 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00171 
00172 #ifndef Vx32_IS_xINT /* don't redefine if types are same */
00173         static void failedAssertNotEqual(Vs32 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00174         static void failedAssertNotEqual(Vu32 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00175 #endif /* not Vx32_IS_xINT */
00176 
00177 #ifndef Vx64_IS_xINT /* don't redefine if types are same */
00178         static void failedAssertNotEqual(Vs64 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00179         static void failedAssertNotEqual(Vu64 val,              const char* expressionA, const char* expressionB, const char* file, int line);
00180 #endif /* not Vx64_IS_xINT */
00181 
00182         static void failedAssertNotEqual(VDouble val,           const char* expressionA, const char* expressionB, const char* file, int line);
00183         static void failedAssertNotEqual(const VString& val,    const char* expressionA, const char* expressionB, const char* file, int line);
00184         static void failedAssertNotEqual(const VCodePoint& val, const char* expressionA, const char* expressionB, const char* file, int line);
00185         static void failedAssertNotEqual(const VChar& val,      const char* expressionA, const char* expressionB, const char* file, int line);
00186         static void failedAssertNotEqual(const VDuration& val,  const char* expressionA, const char* expressionB, const char* file, int line);
00187         static void failedAssertNotEqual(const VInstant& val,   const char* expressionA, const char* expressionB, const char* file, int line);
00188         static void failedAssertNotEqual(const VColor& val,     const char* expressionA, const char* expressionB, const char* file, int line);
00189         static void failedAssertNotEqual(const VColorPair& val, const char* expressionA, const char* expressionB, const char* file, int line);
00190 
00191         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, int a, int b,                              const char* expressionA, const char* expressionB, const char* file, int line);
00192         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, unsigned int a, unsigned int b,            const char* expressionA, const char* expressionB, const char* file, int line);
00193         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, unsigned int a, int b,                     const char* expressionA, const char* expressionB, const char* file, int line);
00194         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs8 a, Vs8 b,                              const char* expressionA, const char* expressionB, const char* file, int line);
00195         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs8 a, int b,                              const char* expressionA, const char* expressionB, const char* file, int line);
00196         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu8 a, Vu8 b,                              const char* expressionA, const char* expressionB, const char* file, int line);
00197         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu8 a, int b,                              const char* expressionA, const char* expressionB, const char* file, int line);
00198         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs16 a, Vs16 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00199         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs16 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00200         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu16 a, Vu16 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00201         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu16 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00202 
00203 #ifndef Vx32_IS_xINT /* don't redefine if types are same */
00204         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs32 a, Vs32 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00205         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs32 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00206         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu32 a, Vu32 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00207         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu32 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00208 #endif /* not Vx32_IS_xINT */
00209 
00210 #ifndef Vx64_IS_xINT /* don't redefine if types are same */
00211         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs64 a, Vs64 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00212         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vs64 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00213         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu64 a, Vu64 b,                            const char* expressionA, const char* expressionB, const char* file, int line);
00214         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, Vu64 a, int b,                             const char* expressionA, const char* expressionB, const char* file, int line);
00215 #endif /* not Vx64_IS_xINT */
00216 
00217         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, VDouble a, VDouble b,                      const char* expressionA, const char* expressionB, const char* file, int line);
00218         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VString& a, const VString& b,        const char* expressionA, const char* expressionB, const char* file, int line);
00219         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VString& a, const char* b,           const char* expressionA, const char* expressionB, const char* file, int line);
00220         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const char* a, const VString& b,           const char* expressionA, const char* expressionB, const char* file, int line);
00221         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VCodePoint& a, const VCodePoint& b,  const char* expressionA, const char* expressionB, const char* file, int line);
00222         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VChar& a, const VChar& b,            const char* expressionA, const char* expressionB, const char* file, int line);
00223         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VChar& a, char b,                    const char* expressionA, const char* expressionB, const char* file, int line);
00224         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VDuration& a, const VDuration& b,    const char* expressionA, const char* expressionB, const char* file, int line);
00225         static void failedLessGreaterComparison(bool comparingLessThan, bool comparingOrEqualTo, const VInstant& a, const VInstant& b,      const char* expressionA, const char* expressionB, const char* file, int line);
00226 
00227         static void failedRangeCheck(int val, int minVal, int maxVal,                                           const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00228         static void failedRangeCheck(unsigned int val, unsigned int minVal, unsigned int maxVal,                const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00229         static void failedRangeCheck(unsigned int val, int minVal, int maxVal,                                  const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00230         // Note: 8- and 16-bit overloads seem to be unnecessary due to up-conversion.
00231 
00232 #ifndef Vx32_IS_xINT /* don't redefine if types are same */
00233         static void failedRangeCheck(Vs32 val, Vs32 minVal, Vs32 maxVal,                                        const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00234         static void failedRangeCheck(Vs32 val, int minVal, int maxVal,                                          const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00235         static void failedRangeCheck(Vu32 val, Vu32 minVal, Vu32 maxVal,                                        const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00236         static void failedRangeCheck(Vu32 val, int minVal, int maxVal,                                          const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00237 #endif /* not Vx32_IS_xINT */
00238 
00239 #ifndef Vx64_IS_xINT /* don't redefine if types are same */
00240         static void failedRangeCheck(Vs64 val, Vs64 minVal, Vs64 maxVal,                                        const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00241         static void failedRangeCheck(Vs64 val, int minVal, int maxVal,                                          const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00242         static void failedRangeCheck(Vu64 val, Vu64 minVal, Vu64 maxVal,                                        const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00243         static void failedRangeCheck(Vu64 val, int minVal, int maxVal,                                          const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00244 #endif /* not Vx64_IS_xINT */
00245 
00246         static void failedRangeCheck(VDouble val, VDouble minVal, VDouble maxVal,                               const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00247         static void failedRangeCheck(const VString& val, const VString& minVal, const VString& maxVal,          const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00248         static void failedRangeCheck(const VCodePoint& val, const VCodePoint& minVal, const VCodePoint& maxVal, const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00249         static void failedRangeCheck(const VChar& val, const VChar& minVal, const VChar& maxVal,                const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00250         static void failedRangeCheck(const VDuration& val, const VDuration& minVal, const VDuration& maxVal,    const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00251         static void failedRangeCheck(const VInstant& val, const VInstant& minVal, const VInstant& maxVal,       const char* valExpression, const char* minValExpression, const char* maxValExpression, const char* file, int line);
00252 
00253     private:
00254 
00255         VAssert() {}
00256         ~VAssert() {}
00257 };
00258 
00259 #endif /* vassert_h */

Copyright ©1997-2014 Trygve Isaacson. All rights reserved. This documentation was generated with Doxygen.