1 #ifndef ASSERT_HELPERS_H_
2 #define ASSERT_HELPERS_H_
3 
4 #include <iostream>
5 #include <stdexcept>
6 #include <string>
7 #include <cassert>
8 
9 /**
10  * Assertion for release-enabled assertions
11  */
12 class ReleaseAssertException : public std::runtime_error {
13 public:
runtime_error(msg)14 	ReleaseAssertException(const std::string& msg = "") : std::runtime_error(msg) {}
15 };
16 
17 /**
18  * Macros for release-enabled assertions, and helper macros to make
19  * all assertion error messages more helpful.
20  */
21 #ifndef NDEBUG
22 #define ASSERT_ONLY(x...) x
23 #else
24 #define ASSERT_ONLY(x...)
25 #endif
26 
27 #define rt_assert(b)  \
28 	if(!(b)) { \
29 		std::cout << "rt_assert at " << __FILE__ << ":" << __LINE__ << std::endl; \
30 		throw ReleaseAssertException(); \
31 	}
32 #define rt_assert_msg(b,msg)  \
33 	if(!(b)) { \
34 		std::cout << msg <<  " at " << __FILE__ << ":" << __LINE__ << std::endl; \
35 		throw ReleaseAssertException(msg); \
36 	}
37 
38 #define rt_assert_eq(ex,ac)  \
39 	if(!((ex) == (ac))) { \
40 		std::cout << "rt_assert_eq: expected (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
41 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
42 		throw ReleaseAssertException(); \
43 	}
44 #define rt_assert_eq_msg(ex,ac,msg)  \
45 	if(!((ex) == (ac))) { \
46 		std::cout << "rt_assert_eq: " << msg <<  ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
47 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
48 		throw ReleaseAssertException(msg); \
49 	}
50 
51 #ifndef NDEBUG
52 #define assert_eq(ex,ac)  \
53 	if(!((ex) == (ac))) { \
54 		std::cout << "assert_eq: expected (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
55 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
56 		assert(0); \
57 	}
58 #define assert_eq_msg(ex,ac,msg)  \
59 	if(!((ex) == (ac))) { \
60 		std::cout << "assert_eq: " << msg <<  ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
61 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
62 		assert(0); \
63 	}
64 #else
65 #define assert_eq(ex,ac)
66 #define assert_eq_msg(ex,ac,msg)
67 #endif
68 
69 #define rt_assert_neq(ex,ac)  \
70 	if(!((ex) != (ac))) { \
71 		std::cout << "rt_assert_neq: expected not (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
72 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
73 		throw ReleaseAssertException(); \
74 	}
75 #define rt_assert_neq_msg(ex,ac,msg)  \
76 	if(!((ex) != (ac))) { \
77 		std::cout << "rt_assert_neq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
78 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
79 		throw ReleaseAssertException(msg); \
80 	}
81 
82 #ifndef NDEBUG
83 #define assert_neq(ex,ac)  \
84 	if(!((ex) != (ac))) { \
85 		std::cout << "assert_neq: expected not (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
86 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
87 		assert(0); \
88 	}
89 #define assert_neq_msg(ex,ac,msg)  \
90 	if(!((ex) != (ac))) { \
91 		std::cout << "assert_neq: " << msg << ": (" << (ex) << ", 0x" << std::hex << (ex) << std::dec << ") got (" << (ac) << ", 0x" << std::hex << (ac) << std::dec << ")" << std::endl; \
92 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
93 		assert(0); \
94 	}
95 #else
96 #define assert_neq(ex,ac)
97 #define assert_neq_msg(ex,ac,msg)
98 #endif
99 
100 #define rt_assert_gt(a,b) \
101 	if(!((a) > (b))) { \
102 		std::cout << "rt_assert_gt: expected (" << (a) << ") > (" << (b) << ")" << std::endl; \
103 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
104 		throw ReleaseAssertException(); \
105 	}
106 #define rt_assert_gt_msg(a,b,msg) \
107 	if(!((a) > (b))) { \
108 		std::cout << "rt_assert_gt: " << msg << ": (" << (a) << ") > (" << (b) << ")" << std::endl; \
109 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
110 		throw ReleaseAssertException(msg); \
111 	}
112 
113 #ifndef NDEBUG
114 #define assert_gt(a,b) \
115 	if(!((a) > (b))) { \
116 		std::cout << "assert_gt: expected (" << (a) << ") > (" << (b) << ")" << std::endl; \
117 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
118 		assert(0); \
119 	}
120 #define assert_gt_msg(a,b,msg) \
121 	if(!((a) > (b))) { \
122 		std::cout << "assert_gt: " << msg << ": (" << (a) << ") > (" << (b) << ")" << std::endl; \
123 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
124 		assert(0); \
125 	}
126 #else
127 #define assert_gt(a,b)
128 #define assert_gt_msg(a,b,msg)
129 #endif
130 
131 #define rt_assert_geq(a,b) \
132 	if(!((a) >= (b))) { \
133 		std::cout << "rt_assert_geq: expected (" << (a) << ") >= (" << (b) << ")" << std::endl; \
134 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
135 		throw ReleaseAssertException(); \
136 	}
137 #define rt_assert_geq_msg(a,b,msg) \
138 	if(!((a) >= (b))) { \
139 		std::cout << "rt_assert_geq: " << msg << ": (" << (a) << ") >= (" << (b) << ")" << std::endl; \
140 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
141 		throw ReleaseAssertException(msg); \
142 	}
143 
144 #ifndef NDEBUG
145 #define assert_geq(a,b) \
146 	if(!((a) >= (b))) { \
147 		std::cout << "assert_geq: expected (" << (a) << ") >= (" << (b) << ")" << std::endl; \
148 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
149 		assert(0); \
150 	}
151 #define assert_geq_msg(a,b,msg) \
152 	if(!((a) >= (b))) { \
153 		std::cout << "assert_geq: " << msg << ": (" << (a) << ") >= (" << (b) << ")" << std::endl; \
154 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
155 		assert(0); \
156 	}
157 #else
158 #define assert_geq(a,b)
159 #define assert_geq_msg(a,b,msg)
160 #endif
161 
162 #define rt_assert_lt(a,b) \
163 	if(!(a < b)) { \
164 		std::cout << "rt_assert_lt: expected (" << a << ") < (" << b << ")" << std::endl; \
165 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
166 		throw ReleaseAssertException(); \
167 	}
168 #define rt_assert_lt_msg(a,b,msg) \
169 	if(!(a < b)) { \
170 		std::cout << "rt_assert_lt: " << msg << ": (" << a << ") < (" << b << ")" << std::endl; \
171 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
172 		throw ReleaseAssertException(msg); \
173 	}
174 
175 #ifndef NDEBUG
176 #define assert_lt(a,b) \
177 	if(!(a < b)) { \
178 		std::cout << "assert_lt: expected (" << a << ") < (" << b << ")" << std::endl; \
179 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
180 		assert(0); \
181 	}
182 #define assert_lt_msg(a,b,msg) \
183 	if(!(a < b)) { \
184 		std::cout << "assert_lt: " << msg << ": (" << a << ") < (" << b << ")" << std::endl; \
185 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
186 		assert(0); \
187 	}
188 #else
189 #define assert_lt(a,b)
190 #define assert_lt_msg(a,b,msg)
191 #endif
192 
193 #define rt_assert_leq(a,b) \
194 	if(!((a) <= (b))) { \
195 		std::cout << "rt_assert_leq: expected (" << (a) << ") <= (" << (b) << ")" << std::endl; \
196 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
197 		throw ReleaseAssertException(); \
198 	}
199 #define rt_assert_leq_msg(a,b,msg) \
200 	if(!((a) <= (b))) { \
201 		std::cout << "rt_assert_leq: " << msg << ": (" << (a) << ") <= (" << (b) << ")" << std::endl; \
202 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
203 		throw ReleaseAssertException(msg); \
204 	}
205 
206 #ifndef NDEBUG
207 #define assert_leq(a,b) \
208 	if(!((a) <= (b))) { \
209 		std::cout << "assert_leq: expected (" << (a) << ") <= (" << (b) << ")" << std::endl; \
210 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
211 		assert(0); \
212 	}
213 #define assert_leq_msg(a,b,msg) \
214 	if(!((a) <= (b))) { \
215 		std::cout << "assert_leq: " << msg << ": (" << (a) << ") <= (" << (b) << ")" << std::endl; \
216 		std::cout << __FILE__ << ":" << __LINE__ << std::endl; \
217 		assert(0); \
218 	}
219 #else
220 #define assert_leq(a,b)
221 #define assert_leq_msg(a,b,msg)
222 #endif
223 
224 #ifndef NDEBUG
225 #define assert_in(c, s) assert_in2(c, s, __FILE__, __LINE__)
assert_in2(char c,const char * str,const char * file,int line)226 static inline void assert_in2(char c, const char *str, const char *file, int line) {
227 	const char *s = str;
228 	while(*s != '\0') {
229 		if(c == *s) return;
230 		s++;
231 	}
232 	std::cout << "assert_in: (" << c << ") not in  (" << str << ")" << std::endl;
233 	std::cout << file << ":" << line << std::endl;
234 	assert(0);
235 }
236 #else
237 #define assert_in(c, s)
238 #endif
239 
240 #ifndef NDEBUG
241 #define assert_range(b, e, v) assert_range_helper(b, e, v, __FILE__, __LINE__)
242 template<typename T>
assert_range_helper(const T & begin,const T & end,const T & val,const char * file,int line)243 inline static void assert_range_helper(const T& begin,
244                                        const T& end,
245                                        const T& val,
246                                        const char *file,
247                                        int line)
248 {
249 	if(val < begin || val > end) {
250 		std::cout << "assert_range: (" << val << ") not in  ["
251 		          << begin << ", " << end << "]" << std::endl;
252 		std::cout << file << ":" << line << std::endl;
253 		assert(0);
254 	}
255 }
256 #else
257 #define assert_range(b, e, v)
258 #endif
259 
260 #endif /*ASSERT_HELPERS_H_*/
261