COIN-OR::LEMON - Graph Library

source: lemon-1.0/lemon/assert.h @ 266:112ed801139d

Last change on this file since 266:112ed801139d was 266:112ed801139d, checked in by Akos Ladanyi <ladanyi@…>, 16 years ago

Use func only if the compiler supports it (ticket #148).

File size: 8.9 KB
RevLine 
[209]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
[66]2 *
[209]3 * This file is a part of LEMON, a generic C++ optimization library.
[66]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
[108]19#ifndef LEMON_ASSERT_H
20#define LEMON_ASSERT_H
[66]21
22/// \ingroup exceptions
23/// \file
[108]24/// \brief Extended assertion handling
[66]25
[108]26#include <lemon/error.h>
[66]27
28namespace lemon {
29
[108]30  inline void assert_fail_log(const char *file, int line, const char *function,
[209]31                              const char *message, const char *assertion)
[66]32  {
[108]33    std::cerr << file << ":" << line << ": ";
34    if (function)
35      std::cerr << function << ": ";
36    std::cerr << message;
[66]37    if (assertion)
[108]38      std::cerr << " (assertion '" << assertion << "' failed)";
39    std::cerr << std::endl;
[66]40  }
41
[108]42  inline void assert_fail_abort(const char *file, int line,
[209]43                                const char *function, const char* message,
44                                const char *assertion)
[108]45  {
[112]46    assert_fail_log(file, line, function, message, assertion);
[108]47    std::abort();
48  }
49
[118]50  namespace _assert_bits {
[209]51
52
[118]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;
[209]59    }
[108]60  }
[118]61}
[108]62
63#endif // LEMON_ASSERT_H
[66]64
65#undef LEMON_ASSERT
66#undef LEMON_FIXME
[118]67#undef LEMON_DEBUG
[66]68
[212]69#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +               \
70  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
[108]71  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
[112]72#error "LEMON assertion system is not set properly"
[66]73#endif
74
[212]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) ||                    \
[118]80   defined(NDEBUG))
[112]81#error "LEMON assertion system is not set properly"
[66]82#endif
83
[108]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"
[66]95#  endif
[108]96#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
[118]97#elif defined LEMON_DISABLE_ASSERTS
[108]98#  undef LEMON_ASSERT_HANDLER
[118]99#elif defined NDEBUG
100#  undef LEMON_ASSERT_HANDLER
101#else
[108]102#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
103#endif
104
105#ifndef LEMON_FUNCTION_NAME
[142]106#  if defined __GNUC__
107#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
108#  elif defined _MSC_VER
109#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
[266]110#  elif __STDC_VERSION__ >= 199901L
111#    define LEMON_FUNCTION_NAME (__func__)
[142]112#  else
[266]113#    define LEMON_FUNCTION_NAME ("<unknown>")
[142]114#  endif
[66]115#endif
116
117#ifdef DOXYGEN
118
[108]119/// \ingroup exceptions
120///
[112]121/// \brief Macro for assertion with customizable message
[66]122///
[118]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.
[66]129///
[118]130/// The assertions are enabled in the default behaviour.
131/// You can disable them with the following code:
[66]132/// \code
[118]133/// #define LEMON_DISABLE_ASSERTS
[66]134/// \endcode
[108]135/// or with compilation parameters:
136/// \code
[118]137/// g++ -DLEMON_DISABLE_ASSERTS
138/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
[108]139/// \endcode
[118]140/// The checking is also disabled when the standard macro \c NDEBUG is defined.
[209]141///
[112]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.
[66]145///
[209]146/// The following modes can be used in the assertion system:
[66]147///
[112]148/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
149///   message to the standard error and continues the execution.
[118]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
152///   behaviour.
[112]153/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
[118]154///   function.
[108]155///   \code
[210]156///     void custom_assert_handler(const char* file, int line,
157///                                const char* function, const char* message,
158///                                const char* assertion);
[108]159///   \endcode
[118]160///   The name of the function should be defined as the \c
[209]161///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
[108]162///   \code
163///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
164///   \endcode
[118]165///   Whenever an assertion is occured, the custom assertion
166///   handler is called with appropiate parameters.
[66]167///
[112]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.
[209]172#  define LEMON_ASSERT(exp, msg)                                        \
[212]173  (static_cast<void> (!!(exp) ? 0 : (                                   \
174    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
175                         LEMON_FUNCTION_NAME,                           \
[209]176                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
[108]177
178/// \ingroup exceptions
[66]179///
[108]180/// \brief Macro for mark not yet implemented features.
181///
182/// Macro for mark not yet implemented features and outstanding bugs.
183/// It is close to be the shortcut of the following code:
184/// \code
185///   LEMON_ASSERT(false, msg);
186/// \endcode
[118]187///
[209]188/// \see LEMON_ASSERT
[212]189#  define LEMON_FIXME(msg)                                              \
[209]190  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,        \
[212]191                        ::lemon::_assert_bits::cstringify(msg),         \
[209]192                        static_cast<const char*>(0)))
[118]193
194/// \ingroup exceptions
195///
196/// \brief Macro for internal assertions
197///
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.
203/// \code
204/// #define LEMON_ENABLE_DEBUG
205/// \endcode
206/// or with compilation parameters:
207/// \code
208/// g++ -DLEMON_ENABLE_DEBUG
209/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
210/// \endcode
211///
212/// This macro works like the \c LEMON_ASSERT macro, therefore the
213/// current behaviour depends on the settings of \c LEMON_ASSERT
214/// macro.
215///
[209]216/// \see LEMON_ASSERT
[212]217#  define LEMON_DEBUG(exp, msg)                                         \
218  (static_cast<void> (!!(exp) ? 0 : (                                   \
[118]219    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
[212]220                         LEMON_FUNCTION_NAME,                           \
[209]221                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
[66]222
223#else
224
[108]225#  ifndef LEMON_ASSERT_HANDLER
[112]226#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
[108]227#    define LEMON_FIXME(msg) (static_cast<void>(0))
[118]228#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
[66]229#  else
[212]230#    define LEMON_ASSERT(exp, msg)                                      \
231       (static_cast<void> (!!(exp) ? 0 : (                              \
[118]232        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
[212]233                             LEMON_FUNCTION_NAME,                       \
234                             ::lemon::_assert_bits::cstringify(msg),    \
[209]235                             #exp), 0)))
[212]236#    define LEMON_FIXME(msg)                                            \
237       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
238                             ::lemon::_assert_bits::cstringify(msg),    \
[209]239                             static_cast<const char*>(0)))
[118]240
241#    if LEMON_ENABLE_DEBUG
[218]242#      define LEMON_DEBUG(exp, msg)                                     \
[212]243         (static_cast<void> (!!(exp) ? 0 : (                            \
244           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
245                                LEMON_FUNCTION_NAME,                    \
246                                ::lemon::_assert_bits::cstringify(msg), \
[209]247                                #exp), 0)))
[118]248#    else
249#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
250#    endif
[66]251#  endif
[108]252
[66]253#endif
Note: See TracBrowser for help on using the repository browser.