-
Notifications
You must be signed in to change notification settings - Fork 6
/
exceptionassert.h
137 lines (115 loc) · 4.94 KB
/
exceptionassert.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef EXCEPTIONASSERT_H
#define EXCEPTIONASSERT_H
#include <string>
#include <stdexcept>
#include <boost/format.hpp>
#include <boost/exception/all.hpp>
// inline type declaration in template argument to error_info without type definition doesn't work on ios
struct errinfo_format_tag {};
typedef boost::error_info<struct errinfo_format_tag, boost::format> errinfo_format;
/**
* @brief The ExceptionAssert class should store details about an assertion
* that failed.
*
* Use like so
*
* try {
* EXCEPTION_ASSERT_EQUALS( 1, 2 );
* } catch (const exception& x) {
* string what = boost::diagnostic_information(x);
* }
*/
class ExceptionAssert: virtual public boost::exception, virtual public std::exception
{
public:
struct message {};
typedef boost::error_info<struct condition,char const *> ExceptionAssert_condition;
typedef boost::error_info<struct message,std::string> ExceptionAssert_message;
// Prevent inlining of creating exception object
static void throwException(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* details,
const std::string&, int skipFrames=0);
static void throwException(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* details,
const boost::format&);
static void logAndThrow(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* details,
const std::string&, int skipFrames=0);
static void logAndThrow(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* details,
const boost::format&);
static void logError(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* condition,
const std::string&);
static void logError(const char* functionMacro,
const char* fileMacro, int lineMacro,
const char* condition,
const boost::format&);
private:
ExceptionAssert();
public:
static void test();
};
#define LOG_ERROR( msg ) \
do { \
ExceptionAssert::logError( BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, "LOG_ERROR", msg ); \
} while(false)
// 'condition' is evaluated once, 'msg' is a boost::format, std::string or compatible type
#define EXCEPTION_ASSERTX( condition, msg ) \
do { \
if (!(condition)) \
ExceptionAssert::throwException( BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, #condition, msg ); \
} while(false)
#define EXCEPTION_ASSERT( condition ) EXCEPTION_ASSERTX( condition, "error" )
#define EXCEPTION_ASSERT_EQUALS( a, b ) \
do { \
const auto& _x = (a); \
const auto& _y = (b); \
EXCEPTION_ASSERTX( _x == _y, boost::format("Equals failed: Got '%1%' = %3%, and '%2%' = %4%") % #a % #b % _x % _y); \
} while(false)
#define EXCEPTION_ASSERT_NOTEQUALS( a, b ) \
do { \
const auto& _x = (a); \
const auto& _y = (b); \
EXCEPTION_ASSERTX( _x != _y, boost::format("Not equals failed: Got '%1%' = %3%, and '%2%' = %4%") % #a % #b % _x % _y); \
} while(false)
#define EXCEPTION_ASSERT_FUZZYEQUALS( a, b, d ) \
do { \
const auto& _x = (a); \
const auto& _y = (b); \
const auto& _z = (d); \
EXCEPTION_ASSERTX( (_x > _y ? _x - _y <= _z : _y - _x <= _z), boost::format("Fuzzy equals failed: Got '%1%' = %3%, and '%2%' = %4%, with diff = %6%, tolerance = %5%") % #a % #b % _x % _y % _z % (_x > _y ? _x - _y : _y - _x)); \
} while(false)
#define EXCEPTION_ASSERT_LESS( a, b ) \
do { \
const auto& _x = (a); \
const auto& _y = (b); \
EXCEPTION_ASSERTX( _x < _y, boost::format("Less failed: Got '%1%' = %3%, and '%2%' = %4%") % #a % #b % _x % _y); \
} while(false)
#define EXCEPTION_ASSERT_LESS_OR_EQUAL( a, b ) \
do { \
const auto& _x = (a); \
const auto& _y = (b); \
EXCEPTION_ASSERTX( _x <= _y, boost::format("Less or equal failed: Got '%1%' = %3%, and '%2%' = %4%") % #a % #b % _x % _y); \
} while(false)
#ifdef _DEBUG
#define EXCEPTION_ASSERTX_DBG EXCEPTION_ASSERTX
#define EXCEPTION_ASSERT_DBG EXCEPTION_ASSERT
#define EXCEPTION_ASSERT_EQUALS_DBG EXCEPTION_ASSERT_EQUALS
#define EXCEPTION_ASSERT_NOTEQUALS_DBG EXCEPTION_ASSERT_NOTEQUALS
#define EXCEPTION_ASSERT_FUZZYEQUALS_DBG EXCEPTION_ASSERT_FUZZYEQUALS
#define EXCEPTION_ASSERT_LESS_DBG EXCEPTION_ASSERT_LESS
#else
#define EXCEPTION_ASSERTX_DBG( condition, msg )
#define EXCEPTION_ASSERT_DBG( condition )
#define EXCEPTION_ASSERT_EQUALS_DBG( a, b )
#define EXCEPTION_ASSERT_NOTEQUALS_DBG( a, b )
#define EXCEPTION_ASSERT_FUZZYEQUALS_DBG( a, b, c )
#define EXCEPTION_ASSERT_LESS_DBG( a, b )
#endif
#endif // EXCEPTIONASSERT_H