COIN-OR::LEMON - Graph Library

source: lemon-1.2/lemon/assert.h @ 503:41bdb4d6c8c3

Last change on this file since 503:41bdb4d6c8c3 was 290:f6899946c1ac, checked in by Balazs Dezso <deba@…>, 16 years ago

Simplifying exceptions

  • Using asserts instead of exceptions for unitialized parameters
  • Only the IO exceptions are used in the lemon
  • DataFormatError? is renamed to FormatError?
  • The IoError? is used for file access errors
File size: 7.4 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
[277]30  inline void assert_fail_abort(const char *file, int line,
31                                const char *function, const char* message,
32                                const char *assertion)
[66]33  {
[108]34    std::cerr << file << ":" << line << ": ";
35    if (function)
36      std::cerr << function << ": ";
37    std::cerr << message;
[66]38    if (assertion)
[108]39      std::cerr << " (assertion '" << assertion << "' failed)";
40    std::cerr << std::endl;
41    std::abort();
42  }
43
[118]44  namespace _assert_bits {
[209]45
46
[118]47    inline const char* cstringify(const std::string& str) {
48      return str.c_str();
49    }
50
51    inline const char* cstringify(const char* str) {
52      return str;
[209]53    }
[108]54  }
[118]55}
[108]56
57#endif // LEMON_ASSERT_H
[66]58
59#undef LEMON_ASSERT
[118]60#undef LEMON_DEBUG
[66]61
[277]62#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
[108]63  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
[112]64#error "LEMON assertion system is not set properly"
[66]65#endif
66
[277]67#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
[212]68     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
69     defined(LEMON_ENABLE_ASSERTS)) &&                  \
70  (defined(LEMON_DISABLE_ASSERTS) ||                    \
[118]71   defined(NDEBUG))
[112]72#error "LEMON assertion system is not set properly"
[66]73#endif
74
[108]75
[277]76#if defined LEMON_ASSERT_ABORT
[108]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"
[66]83#  endif
[108]84#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
[118]85#elif defined LEMON_DISABLE_ASSERTS
[108]86#  undef LEMON_ASSERT_HANDLER
[118]87#elif defined NDEBUG
88#  undef LEMON_ASSERT_HANDLER
89#else
[108]90#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91#endif
92
93#ifndef LEMON_FUNCTION_NAME
[142]94#  if defined __GNUC__
95#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
96#  elif defined _MSC_VER
97#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
[266]98#  elif __STDC_VERSION__ >= 199901L
99#    define LEMON_FUNCTION_NAME (__func__)
[142]100#  else
[266]101#    define LEMON_FUNCTION_NAME ("<unknown>")
[142]102#  endif
[66]103#endif
104
105#ifdef DOXYGEN
106
[108]107/// \ingroup exceptions
108///
[112]109/// \brief Macro for assertion with customizable message
[66]110///
[290]111/// Macro for assertion with customizable message.
[277]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.
[66]117///
[118]118/// The assertions are enabled in the default behaviour.
119/// You can disable them with the following code:
[66]120/// \code
[118]121/// #define LEMON_DISABLE_ASSERTS
[66]122/// \endcode
[108]123/// or with compilation parameters:
124/// \code
[118]125/// g++ -DLEMON_DISABLE_ASSERTS
126/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
[108]127/// \endcode
[118]128/// The checking is also disabled when the standard macro \c NDEBUG is defined.
[209]129///
[277]130/// As a default behaviour the failed assertion prints a short log message to
131/// the standard error and aborts the execution.
[66]132///
[277]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.
[112]136/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
[118]137///   function.
[108]138///   \code
[210]139///     void custom_assert_handler(const char* file, int line,
140///                                const char* function, const char* message,
141///                                const char* assertion);
[108]142///   \endcode
[118]143///   The name of the function should be defined as the \c
[209]144///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
[108]145///   \code
146///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
147///   \endcode
[118]148///   Whenever an assertion is occured, the custom assertion
149///   handler is called with appropiate parameters.
[66]150///
[112]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.
[209]155#  define LEMON_ASSERT(exp, msg)                                        \
[212]156  (static_cast<void> (!!(exp) ? 0 : (                                   \
157    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
158                         LEMON_FUNCTION_NAME,                           \
[209]159                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
[108]160
161/// \ingroup exceptions
[66]162///
[118]163/// \brief Macro for internal assertions
164///
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.
170/// \code
171/// #define LEMON_ENABLE_DEBUG
172/// \endcode
173/// or with compilation parameters:
174/// \code
175/// g++ -DLEMON_ENABLE_DEBUG
176/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
177/// \endcode
178///
179/// This macro works like the \c LEMON_ASSERT macro, therefore the
180/// current behaviour depends on the settings of \c LEMON_ASSERT
181/// macro.
182///
[209]183/// \see LEMON_ASSERT
[212]184#  define LEMON_DEBUG(exp, msg)                                         \
185  (static_cast<void> (!!(exp) ? 0 : (                                   \
[118]186    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
[212]187                         LEMON_FUNCTION_NAME,                           \
[209]188                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
[66]189
190#else
191
[108]192#  ifndef LEMON_ASSERT_HANDLER
[112]193#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
[118]194#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
[66]195#  else
[212]196#    define LEMON_ASSERT(exp, msg)                                      \
197       (static_cast<void> (!!(exp) ? 0 : (                              \
[118]198        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
[212]199                             LEMON_FUNCTION_NAME,                       \
200                             ::lemon::_assert_bits::cstringify(msg),    \
[209]201                             #exp), 0)))
[118]202#    if LEMON_ENABLE_DEBUG
[218]203#      define LEMON_DEBUG(exp, msg)                                     \
[212]204         (static_cast<void> (!!(exp) ? 0 : (                            \
205           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
206                                LEMON_FUNCTION_NAME,                    \
207                                ::lemon::_assert_bits::cstringify(msg), \
[209]208                                #exp), 0)))
[118]209#    else
210#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
211#    endif
[66]212#  endif
[108]213
[66]214#endif
Note: See TracBrowser for help on using the repository browser.