1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2009
 
     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_abort(const char *file, int line,
 
    31                                 const char *function, const char* message,
 
    32                                 const char *assertion)
 
    34     std::cerr << file << ":" << line << ": ";
 
    36       std::cerr << function << ": ";
 
    39       std::cerr << " (assertion '" << assertion << "' failed)";
 
    40     std::cerr << std::endl;
 
    44   namespace _assert_bits {
 
    47     inline const char* cstringify(const std::string& str) {
 
    51     inline const char* cstringify(const char* str) {
 
    57 #endif // LEMON_ASSERT_H
 
    62 #if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
 
    63   (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
 
    64 #error "LEMON assertion system is not set properly"
 
    67 #if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
 
    68      (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
 
    69      defined(LEMON_ENABLE_ASSERTS)) &&                  \
 
    70   (defined(LEMON_DISABLE_ASSERTS) ||                    \
 
    72 #error "LEMON assertion system is not set properly"
 
    76 #if defined LEMON_ASSERT_ABORT
 
    77 #  undef LEMON_ASSERT_HANDLER
 
    78 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
 
    79 #elif defined LEMON_ASSERT_CUSTOM
 
    80 #  undef LEMON_ASSERT_HANDLER
 
    81 #  ifndef LEMON_CUSTOM_ASSERT_HANDLER
 
    82 #    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
 
    84 #  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
 
    85 #elif defined LEMON_DISABLE_ASSERTS
 
    86 #  undef LEMON_ASSERT_HANDLER
 
    88 #  undef LEMON_ASSERT_HANDLER
 
    90 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
 
    93 #ifndef LEMON_FUNCTION_NAME
 
    95 #    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
 
    96 #  elif defined _MSC_VER
 
    97 #    define LEMON_FUNCTION_NAME (__FUNCSIG__)
 
    98 #  elif __STDC_VERSION__ >= 199901L
 
    99 #    define LEMON_FUNCTION_NAME (__func__)
 
   101 #    define LEMON_FUNCTION_NAME ("<unknown>")
 
   107 /// \ingroup exceptions
 
   109 /// \brief Macro for assertion with customizable message
 
   111 /// Macro for assertion with customizable message.
 
   112 /// \param exp An expression that must be convertible to \c bool.  If it is \c
 
   113 /// false, then an assertion is raised. The concrete behaviour depends on the
 
   114 /// settings of the assertion system.
 
   115 /// \param msg A <tt>const char*</tt> parameter, which can be used to provide
 
   116 /// information about the circumstances of the failed assertion.
 
   118 /// The assertions are enabled in the default behaviour.
 
   119 /// You can disable them with the following code:
 
   121 /// #define LEMON_DISABLE_ASSERTS
 
   123 /// or with compilation parameters:
 
   125 /// g++ -DLEMON_DISABLE_ASSERTS
 
   126 /// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
 
   128 /// The checking is also disabled when the standard macro \c NDEBUG is defined.
 
   130 /// As a default behaviour the failed assertion prints a short log message to
 
   131 /// the standard error and aborts the execution.
 
   133 /// However, the following modes can be used in the assertion system:
 
   134 /// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
 
   135 ///   the standard error and aborts the program. It is the default behaviour.
 
   136 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
 
   139 ///     void custom_assert_handler(const char* file, int line,
 
   140 ///                                const char* function, const char* message,
 
   141 ///                                const char* assertion);
 
   143 ///   The name of the function should be defined as the \c
 
   144 ///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
 
   146 ///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
 
   148 ///   Whenever an assertion is occured, the custom assertion
 
   149 ///   handler is called with appropiate parameters.
 
   151 /// The assertion mode can also be changed within one compilation unit.
 
   152 /// If the macros are redefined with other settings and the
 
   153 /// \ref lemon/assert.h "assert.h" file is reincluded, then the
 
   154 /// behaviour is changed appropiately to the new settings.
 
   155 #  define LEMON_ASSERT(exp, msg)                                        \
 
   156   (static_cast<void> (!!(exp) ? 0 : (                                   \
 
   157     LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
 
   158                          LEMON_FUNCTION_NAME,                           \
 
   159                          ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
   161 /// \ingroup exceptions
 
   163 /// \brief Macro for internal assertions
 
   165 /// Macro for internal assertions, it is used in the library to check
 
   166 /// the consistency of results of algorithms, several pre- and
 
   167 /// postconditions and invariants. The checking is disabled by
 
   168 /// default, but it can be turned on with the macro \c
 
   169 /// LEMON_ENABLE_DEBUG.
 
   171 /// #define LEMON_ENABLE_DEBUG
 
   173 /// or with compilation parameters:
 
   175 /// g++ -DLEMON_ENABLE_DEBUG
 
   176 /// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
 
   179 /// This macro works like the \c LEMON_ASSERT macro, therefore the
 
   180 /// current behaviour depends on the settings of \c LEMON_ASSERT
 
   183 /// \see LEMON_ASSERT
 
   184 #  define LEMON_DEBUG(exp, msg)                                         \
 
   185   (static_cast<void> (!!(exp) ? 0 : (                                   \
 
   186     LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
 
   187                          LEMON_FUNCTION_NAME,                           \
 
   188                          ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
   192 #  ifndef LEMON_ASSERT_HANDLER
 
   193 #    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
 
   194 #    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
 
   196 #    define LEMON_ASSERT(exp, msg)                                      \
 
   197        (static_cast<void> (!!(exp) ? 0 : (                              \
 
   198         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
 
   199                              LEMON_FUNCTION_NAME,                       \
 
   200                              ::lemon::_assert_bits::cstringify(msg),    \
 
   202 #    if LEMON_ENABLE_DEBUG
 
   203 #      define LEMON_DEBUG(exp, msg)                                     \
 
   204          (static_cast<void> (!!(exp) ? 0 : (                            \
 
   205            LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
 
   206                                 LEMON_FUNCTION_NAME,                    \
 
   207                                 ::lemon::_assert_bits::cstringify(msg), \
 
   210 #      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))