source: trunk/src/lol/base/assert.h @ 2506

Last change on this file since 2506 was 2506, checked in by sam, 7 years ago

base: start removing occurrences of NULL on our long journey to nullptr.

File size: 4.3 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11#if !defined __LOL_BASE_ASSERT_H__
12#define __LOL_BASE_ASSERT_H__
13
14#include <cstdlib>
15
16namespace lol
17{
18
19static inline void Abort()
20{
21#if defined __CELLOS_LV2__
22    *(uint32_t *)nullptr = 0xdead;
23#else
24    std::abort();
25#endif
26}
27
28/* FIXME: see http://stackoverflow.com/q/3596781/111461 for discussions
29 * on implementing __debugbreak() on POSIX systems. */
30static inline void DebugBreak()
31{
32#if defined _WIN32
33    __debugbreak();
34#endif
35}
36
37extern void DumpStack();
38
39#define LOL_CALL(macro, args) macro args
40#define LOL_EVAL(a) a
41#define LOL_1ST(a, ...) a
42
43#define LOL_GET_63RD(a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, \
44                     a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \
45                     a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \
46                     a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \
47                     a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \
48                     a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, \
49                     a61, a62, a63, ...) a63
50#define LOL_COUNT_TO_3(...) \
51    LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
52                                       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
53                                       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
54                                       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
55                                       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
56                                       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
57                                       2, 1, TOO_FEW_ARGUMENTS))
58#define LOL_COUNT_TO_8(...) \
59    LOL_EVAL(LOL_GET_63RD(__VA_ARGS__, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
60                                       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
61                                       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
62                                       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
63                                       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, \
64                                       8, 8, 8, 8, 8, 7, 6, 5, 4, 3, \
65                                       2, 1, TOO_FEW_ARGUMENTS))
66
67/* Three levels of dispatch are needed because of Visual Studio's bizarre
68 * handling of __VA_ARGS__ inside macro calls */
69#define LOL_CAT3(a, b) a##b
70#define LOL_CAT2(a, b) LOL_CAT3(a,b)
71#define LOL_CAT(a, b) LOL_CAT2(a,b)
72
73/*
74 * UNUSED(): declare one or several variables as unused
75 */
76
77#define LOL_UNUSED_1(a01) \
78    sizeof(a01)
79#define LOL_UNUSED_2(a01, a02) \
80    sizeof(a01) + LOL_UNUSED_1(a02)
81#define LOL_UNUSED_3(a01, a02, a03) \
82    sizeof(a01) + LOL_UNUSED_2(a02, a03)
83#define LOL_UNUSED_4(a01, a02, a03, a04) \
84    sizeof(a01) + LOL_UNUSED_3(a02, a03, a04)
85#define LOL_UNUSED_5(a01, a02, a03, a04, a05) \
86    sizeof(a01) + LOL_UNUSED_4(a02, a03, a04, a05)
87#define LOL_UNUSED_6(a01, a02, a03, a04, a05, a06) \
88    sizeof(a01) + LOL_UNUSED_5(a02, a03, a04, a05, a06)
89#define LOL_UNUSED_7(a01, a02, a03, a04, a05, a06, a07) \
90    sizeof(a01) + LOL_UNUSED_6(a02, a03, a04, a05, a06, a07)
91#define LOL_UNUSED_8(a01, a02, a03, a04, a05, a06, a07, a08) \
92    sizeof(a01) + LOL_UNUSED_7(a02, a03, a04, a05, a06, a07, a08)
93
94#define UNUSED(...) (void)sizeof((void)( \
95    LOL_CALL(LOL_CAT(LOL_UNUSED_, LOL_CALL(LOL_COUNT_TO_8, (__VA_ARGS__))), \
96             (__VA_ARGS__))), 0) \
97
98/*
99 * ASSERT(): test and enforce conditions at runtime
100 */
101
102#define LOL_ERROR_1(t) \
103    Log::Error("assertion failure: " #t "\n")
104
105#define LOL_ERROR_2(t, s) \
106    Log::Error("assertion failure: %s\n", s)
107
108#define LOL_ERROR_3(t, s, ...) \
109    Log::Error("assertion failure: " s "\n", __VA_ARGS__)
110
111#if FINAL_RELEASE
112#   define ASSERT(...) UNUSED(LOL_CALL(LOL_1ST, (__VA_ARGS__)))
113#else
114#   define ASSERT(...) \
115        if (!(LOL_CALL(LOL_1ST, (__VA_ARGS__)))) \
116        { \
117            LOL_CALL(LOL_CAT(LOL_ERROR_, LOL_CALL(LOL_COUNT_TO_3, \
118                                                  (__VA_ARGS__))), \
119                     (__VA_ARGS__)); \
120            DumpStack(); \
121            DebugBreak(); \
122            Abort(); \
123        }
124#endif
125
126} /* namespace lol */
127
128#endif // __LOL_BASE_ASSERT_H__
129
Note: See TracBrowser for help on using the repository browser.