CACAO
assert.hpp
Go to the documentation of this file.
1 /* src/toolbox/assert.hpp - Additional assertion macros
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #ifndef ASSERT_HPP_
27 #define ASSERT_HPP_ 1
28 
29 #include <cassert> // for assert
30 #include "config.h" // for HAS_BUILTIN_STATIC_ASSERT, ENABLE_EXPENSIVE_ASSERT
31 
32 /**
33  * @file
34  * Additional assertion macros
35  */
36 
37 /**
38  * @def STATIC_ASSERT(EXPR, MSG)
39  * An assertion that is evaluated at compile time.
40  *
41  * The evaluated expression must be a compile time constant.
42  *
43  * If possible this uses the C++11 static_assert feature, otherwise it uses
44  * a fallback that produces substantially worse error messages.
45  *
46  * A static assert can appear anywhere a typedef can, that is, in global,
47  * class or function scope.
48  * In order to support disabling static assertions STATIC_ASSERT does not require a trailing ';'
49  *
50  * An example:
51  * @code
52  * STATIC_ASSERT(1 + 1 == 2, "Math is hard") // compiles without error
53  * STATIC_ASSERT(5 > 6, "Math is hard") // causes a compilation error
54  * @endcode
55  *
56  * @remark The fallback version cannot handle multiple STATIC_ASSERTs on one line.
57  */
58 #ifdef HAS_BUILTIN_STATIC_ASSERT
59 # define STATIC_ASSERT(EXPR, MSG) static_assert(EXPR, MSG);
60 #else
61 # define STATIC_ASSERT(EXPR, MSG) \
62  typedef ::cacao::static_assert_test< \
63  sizeof(::cacao::STATIC_ASSERTION_FAILURE<static_cast<bool>((EXPR))>) \
64  > CONCAT(static_assert_, __LINE__) __attribute__((unused));
65 
66  namespace cacao {
67  template <bool expr> struct STATIC_ASSERTION_FAILURE;
68 
69  template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
70 
71  // STATIC_ASSERTION_FAILURE<false> is undefined, that's the whole trick
72 
73  template<int expr> struct static_assert_test {};
74  }
75 # define CONCAT(A, B) CONCAT_(A, B)
76 # define CONCAT_(A, B) A ## B
77 #endif
78 
79 
80 /**
81  * @def EXPENSIVE_ASSERT(EXPR)
82  * An assertion that performs computations too expensive even for a normal
83  * debug build.
84  *
85  * EXPENSIVE_ASSERT is even disabled in a normal debug build.
86  * You can enable these assertions explicitly by configuring CACAO with:
87  * --enable-expensive-assert
88  */
89 #ifdef ENABLE_EXPENSIVE_ASSERT
90 # define EXPENSIVE_ASSERT(EXPR) assert(EXPR)
91 #else
92 # define EXPENSIVE_ASSERT(EXPR) (static_cast<void>(0))
93 #endif
94 
95 
96 #endif // ASSERT_HPP_
97 
98 /*
99  * These are local overrides for various environment variables in Emacs.
100  * Please do not remove this and leave it at the end of the file, where
101  * Emacs will automagically detect them.
102  * ---------------------------------------------------------------------
103  * Local variables:
104  * mode: c++
105  * indent-tabs-mode: t
106  * c-basic-offset: 4
107  * tab-width: 4
108  * End:
109  * vim:noexpandtab:sw=4:ts=4:
110  */