COIN-OR::LEMON - Graph Library

source: lemon-1.0/lemon/assert.h @ 118:407c08a0eae9

Last change on this file since 118:407c08a0eae9 was 118:407c08a0eae9, checked in by Balazs Dezso <deba@…>, 11 years ago

Exception related solutions removed and new LEMON_DEBUG macro

File size: 7.8 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
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.
12 *
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
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_ASSERT_H
20#define LEMON_ASSERT_H
21
22/// \ingroup exceptions
23/// \file
24/// \brief Extended assertion handling
25
26#include <lemon/error.h>
27
28namespace lemon {
29
30  inline void assert_fail_log(const char *file, int line, const char *function,
31                              const char *message, const char *assertion)
32  {
33    std::cerr << file << ":" << line << ": ";
34    if (function)
35      std::cerr << function << ": ";
36    std::cerr << message;
37    if (assertion)
38      std::cerr << " (assertion '" << assertion << "' failed)";
39    std::cerr << std::endl;
40  }
41
42  inline void assert_fail_abort(const char *file, int line,
43                                const char *function, const char* message,
44                                const char *assertion)
45  {
46    assert_fail_log(file, line, function, message, assertion);
47    std::abort();
48  }
49
50  namespace _assert_bits {
51   
52   
53    inline const char* cstringify(const std::string& str) {
54      return str.c_str();
55    }
56
57    inline const char* cstringify(const char* str) {
58      return str;
59    }   
60  }
61}
62
63#endif // LEMON_ASSERT_H
64
65#undef LEMON_ASSERT
66#undef LEMON_FIXME
67#undef LEMON_DEBUG
68
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"
73#endif
74
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) ||                    \
80   defined(NDEBUG))
81#error "LEMON assertion system is not set properly"
82#endif
83
84
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"
95#  endif
96#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
97#elif defined LEMON_DISABLE_ASSERTS
98#  undef LEMON_ASSERT_HANDLER
99#elif defined NDEBUG
100#  undef LEMON_ASSERT_HANDLER
101#else
102#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
103#endif
104
105#ifndef LEMON_FUNCTION_NAME
106#  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
107#endif
108
109#ifdef DOXYGEN
110
111/// \ingroup exceptions
112///
113/// \brief Macro for assertion with customizable message
114///
115/// Macro for assertion with customizable message.  \param exp An
116/// expression that must be convertible to \c bool.  If it is \c
117/// false, then an assertion is raised. The concrete behaviour depends
118/// on the settings of the assertion system.  \param msg A <tt>const
119/// char*</tt> parameter, which can be used to provide information
120/// about the circumstances of the failed assertion.
121///
122/// The assertions are enabled in the default behaviour.
123/// You can disable them with the following code:
124/// \code
125/// #define LEMON_DISABLE_ASSERTS
126/// \endcode
127/// or with compilation parameters:
128/// \code
129/// g++ -DLEMON_DISABLE_ASSERTS
130/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
131/// \endcode
132/// The checking is also disabled when the standard macro \c NDEBUG is defined.
133///
134/// The LEMON assertion system has a wide range of customization
135/// properties. As a default behaviour the failed assertion prints a
136/// short log message to the standard error and aborts the execution.
137///
138/// The following modes can be used in the assertion system:
139///
140/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
141///   message to the standard error and continues the execution.
142/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
143///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
144///   behaviour.
145/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
146///   function.
147///   \code
148///     void custom_assert_handler(const char* file, int line, const char* function,
149///                                const char* message, const char* assertion);
150///   \endcode
151///   The name of the function should be defined as the \c
152///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
153///   \code
154///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
155///   \endcode
156///   Whenever an assertion is occured, the custom assertion
157///   handler is called with appropiate parameters.
158///
159/// The assertion mode can also be changed within one compilation unit.
160/// If the macros are redefined with other settings and the
161/// \ref lemon/assert.h "assert.h" file is reincluded, then the
162/// behaviour is changed appropiately to the new settings.
163#  define LEMON_ASSERT(exp, msg)                                        \
164  (static_cast<void> (!!(exp) ? 0 : (                                   \
165    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
166                         LEMON_FUNCTION_NAME,                           \
167                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
168
169/// \ingroup exceptions
170///
171/// \brief Macro for mark not yet implemented features.
172///
173/// Macro for mark not yet implemented features and outstanding bugs.
174/// It is close to be the shortcut of the following code:
175/// \code
176///   LEMON_ASSERT(false, msg);
177/// \endcode
178///
179/// \see LEMON_ASSERT
180#  define LEMON_FIXME(msg)                                              \
181  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,        \
182                        ::lemon::_assert_bits::cstringify(msg),         \
183                        static_cast<const char*>(0)))
184
185/// \ingroup exceptions
186///
187/// \brief Macro for internal assertions
188///
189/// Macro for internal assertions, it is used in the library to check
190/// the consistency of results of algorithms, several pre- and
191/// postconditions and invariants. The checking is disabled by
192/// default, but it can be turned on with the macro \c
193/// LEMON_ENABLE_DEBUG.
194/// \code
195/// #define LEMON_ENABLE_DEBUG
196/// \endcode
197/// or with compilation parameters:
198/// \code
199/// g++ -DLEMON_ENABLE_DEBUG
200/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
201/// \endcode
202///
203/// This macro works like the \c LEMON_ASSERT macro, therefore the
204/// current behaviour depends on the settings of \c LEMON_ASSERT
205/// macro.
206///
207/// \see LEMON_ASSERT
208#  define LEMON_DEBUG(exp, msg)                                         \
209  (static_cast<void> (!!(exp) ? 0 : (                                   \
210    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
211                         LEMON_FUNCTION_NAME,                           \
212                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
213
214#else
215
216#  ifndef LEMON_ASSERT_HANDLER
217#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
218#    define LEMON_FIXME(msg) (static_cast<void>(0))
219#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
220#  else
221#    define LEMON_ASSERT(exp, msg)                                      \
222       (static_cast<void> (!!(exp) ? 0 : (                              \
223        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
224                             LEMON_FUNCTION_NAME,                       \
225                             ::lemon::_assert_bits::cstringify(msg),    \
226                             #exp), 0)))
227#    define LEMON_FIXME(msg)                                            \
228       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
229                             ::lemon::_assert_bits::cstringify(msg),    \
230                             static_cast<const char*>(0)))
231
232#    if LEMON_ENABLE_DEBUG
233#      define LEMON_DEBUG(exp, msg)
234         (static_cast<void> (!!(exp) ? 0 : (         \
235           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
236                                LEMON_FUNCTION_NAME, \
237                                ::lemon::_assert_bits::cstringify(msg), \
238                                #exp), 0)))
239#    else
240#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
241#    endif
242#  endif
243
244#endif
245
246#ifdef DOXYGEN
247
248
249#else
250
251
252#endif
253
254
Note: See TracBrowser for help on using the repository browser.