1/*
2	advanced assert() definition
3
4	code under LGPL
5	created by Albert Zeyer, on 15-03-2009
6*/
7
8#include <cctype>
9
10
11#ifndef TOSTRING
12#define STRINGIFY(x) #x
13#define TOSTRING(x) STRINGIFY(x)
14#endif
15
16
17#undef assert_failed
18#ifdef _MSC_VER
19#	define assert_failed(x) { printf("Assertion %s failed: %s in %s:%i\n", TOSTRING(x), (__FUNCSIG__), (__FILE__), (__LINE__)); __asm  { int 3 }; }
20#else
21#	ifdef __GNUC__
22#		define assert_failed(x) { printf("Assertion %s failed: %s in %s:%i\n", TOSTRING(x), __FUNCTION__, __FILE__, __LINE__); abort(); }
23#	else
24#		define assert_failed(x) { printf("Assertion %s failed: in %s:%i\n", TOSTRING(x), __FILE__, __LINE__); abort(); }
25#	endif
26#endif
27
28
29#undef rt_assert
30#define rt_assert(x) { if(!(x)) { assert_failed(x); } }
31
32
33// We will get multiple compiler errors for this (and we want these).
34// It should give a linker error for an unresolved symbol.
35void assert_failed_statically (void)
36#if defined(__GNUC__) &&  __GNUC_PREREQ(4,3)
37// In this case, we can print an error even earlier.
38__attribute__((error("assertion always false")))
39#endif
40;
41
42
43#undef is_known_at_ct
44#ifdef __GNUC__
45#	define is_known_at_ct(x)	__builtin_constant_p(x)
46#else
47// TODO ...
48#	define is_known_at_ct(x)	0
49#endif
50
51
52#undef assert
53#define assert(x)	{ \
54	if(is_known_at_ct(!(x))) { \
55		if(strcmp(TOSTRING(x), "false") == 0) { rt_assert(x); } \
56 		else if(!(x)) assert_failed_statically(); } \
57	else rt_assert(x); }
58
59