1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_ASSERT_H
20 #define LEMON_ASSERT_H
22 /// \ingroup exceptions
24 /// \brief Extended assertion handling
26 #include <lemon/error.h>
30 inline void assert_fail_log(const char *file, int line, const char *function,
31 const char *message, const char *assertion)
33 std::cerr << file << ":" << line << ": ";
35 std::cerr << function << ": ";
38 std::cerr << " (assertion '" << assertion << "' failed)";
39 std::cerr << std::endl;
42 inline void assert_fail_abort(const char *file, int line,
43 const char *function, const char* message,
44 const char *assertion)
46 assert_fail_log(file, line, function, message, assertion);
50 namespace _assert_bits {
53 inline const char* cstringify(const std::string& str) {
57 inline const char* cstringify(const char* str) {
63 #endif // LEMON_ASSERT_H
69 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \
70 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
71 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
72 #error "LEMON assertion system is not set properly"
75 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \
76 (defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \
77 (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \
78 defined(LEMON_ENABLE_ASSERTS)) && \
79 (defined(LEMON_DISABLE_ASSERTS) || \
81 #error "LEMON assertion system is not set properly"
85 #if defined LEMON_ASSERT_LOG
86 # undef LEMON_ASSERT_HANDLER
87 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_log
88 #elif defined LEMON_ASSERT_ABORT
89 # undef LEMON_ASSERT_HANDLER
90 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 #elif defined LEMON_ASSERT_CUSTOM
92 # undef LEMON_ASSERT_HANDLER
93 # ifndef LEMON_CUSTOM_ASSERT_HANDLER
94 # error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
96 # define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
97 #elif defined LEMON_DISABLE_ASSERTS
98 # undef LEMON_ASSERT_HANDLER
100 # undef LEMON_ASSERT_HANDLER
102 # define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
105 #ifndef LEMON_FUNCTION_NAME
106 # if defined __GNUC__
107 # define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
108 # elif defined _MSC_VER
109 # define LEMON_FUNCTION_NAME (__FUNCSIG__)
110 # elif __STDC_VERSION__ >= 199901L
111 # define LEMON_FUNCTION_NAME (__func__)
113 # define LEMON_FUNCTION_NAME ("<unknown>")
119 /// \ingroup exceptions
121 /// \brief Macro for assertion with customizable message
123 /// Macro for assertion with customizable message. \param exp An
124 /// expression that must be convertible to \c bool. If it is \c
125 /// false, then an assertion is raised. The concrete behaviour depends
126 /// on the settings of the assertion system. \param msg A <tt>const
127 /// char*</tt> parameter, which can be used to provide information
128 /// about the circumstances of the failed assertion.
130 /// The assertions are enabled in the default behaviour.
131 /// You can disable them with the following code:
133 /// #define LEMON_DISABLE_ASSERTS
135 /// or with compilation parameters:
137 /// g++ -DLEMON_DISABLE_ASSERTS
138 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
140 /// The checking is also disabled when the standard macro \c NDEBUG is defined.
142 /// The LEMON assertion system has a wide range of customization
143 /// properties. As a default behaviour the failed assertion prints a
144 /// short log message to the standard error and aborts the execution.
146 /// The following modes can be used in the assertion system:
148 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
149 /// message to the standard error and continues the execution.
150 /// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
151 /// LEMON_ASSERT_LOG, but it aborts the program. It is the default
153 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
156 /// void custom_assert_handler(const char* file, int line,
157 /// const char* function, const char* message,
158 /// const char* assertion);
160 /// The name of the function should be defined as the \c
161 /// LEMON_CUSTOM_ASSERT_HANDLER macro name.
163 /// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
165 /// Whenever an assertion is occured, the custom assertion
166 /// handler is called with appropiate parameters.
168 /// The assertion mode can also be changed within one compilation unit.
169 /// If the macros are redefined with other settings and the
170 /// \ref lemon/assert.h "assert.h" file is reincluded, then the
171 /// behaviour is changed appropiately to the new settings.
172 # define LEMON_ASSERT(exp, msg) \
173 (static_cast<void> (!!(exp) ? 0 : ( \
174 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
175 LEMON_FUNCTION_NAME, \
176 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
178 /// \ingroup exceptions
180 /// \brief Macro for mark not yet implemented features.
182 /// Macro for mark not yet implemented features and outstanding bugs.
183 /// It is close to be the shortcut of the following code:
185 /// LEMON_ASSERT(false, msg);
188 /// \see LEMON_ASSERT
189 # define LEMON_FIXME(msg) \
190 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \
191 ::lemon::_assert_bits::cstringify(msg), \
192 static_cast<const char*>(0)))
194 /// \ingroup exceptions
196 /// \brief Macro for internal assertions
198 /// Macro for internal assertions, it is used in the library to check
199 /// the consistency of results of algorithms, several pre- and
200 /// postconditions and invariants. The checking is disabled by
201 /// default, but it can be turned on with the macro \c
202 /// LEMON_ENABLE_DEBUG.
204 /// #define LEMON_ENABLE_DEBUG
206 /// or with compilation parameters:
208 /// g++ -DLEMON_ENABLE_DEBUG
209 /// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
212 /// This macro works like the \c LEMON_ASSERT macro, therefore the
213 /// current behaviour depends on the settings of \c LEMON_ASSERT
216 /// \see LEMON_ASSERT
217 # define LEMON_DEBUG(exp, msg) \
218 (static_cast<void> (!!(exp) ? 0 : ( \
219 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
220 LEMON_FUNCTION_NAME, \
221 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
225 # ifndef LEMON_ASSERT_HANDLER
226 # define LEMON_ASSERT(exp, msg) (static_cast<void>(0))
227 # define LEMON_FIXME(msg) (static_cast<void>(0))
228 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
230 # define LEMON_ASSERT(exp, msg) \
231 (static_cast<void> (!!(exp) ? 0 : ( \
232 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
233 LEMON_FUNCTION_NAME, \
234 ::lemon::_assert_bits::cstringify(msg), \
236 # define LEMON_FIXME(msg) \
237 (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \
238 ::lemon::_assert_bits::cstringify(msg), \
239 static_cast<const char*>(0)))
241 # if LEMON_ENABLE_DEBUG
242 # define LEMON_DEBUG(exp, msg) \
243 (static_cast<void> (!!(exp) ? 0 : ( \
244 LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
245 LEMON_FUNCTION_NAME, \
246 ::lemon::_assert_bits::cstringify(msg), \
249 # define LEMON_DEBUG(exp, msg) (static_cast<void>(0))