COIN-OR::LEMON - Graph Library

Changeset 118:407c08a0eae9 in lemon-1.2 for lemon


Ignore:
Timestamp:
04/11/08 16:20:54 (17 years ago)
Author:
Balazs Dezso <deba@…>
Branch:
default
Phase:
public
Message:

Exception related solutions removed and new LEMON_DEBUG macro

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/assert.h

    r112 r118  
    2727
    2828namespace lemon {
    29 
    30   /// @{
    31 
    32   ///\e
    33   class AssertionFailedError : public LogicError {
    34   protected:
    35     const char *_assertion;
    36     const char *_file;
    37     int _line;
    38     const char *_function;
    39     const char *_message;
    40 
    41     mutable ExceptionMember<std::string> _message_holder;
    42   public:
    43     ///\e
    44     AssertionFailedError(const char *file, int line, const char *function,
    45                          const char *msg, const char *assertion = 0) :
    46       _assertion(assertion), _file(file), _line(line),
    47       _function(function), _message(msg) {}
    48 
    49     ///\e
    50     const char* assertion() const { return _assertion; }
    51     ///\e
    52     const char* message() const { return _message; }
    53     ///\e
    54     const char* file() const { return _file; }
    55     ///\e
    56     const char* function() const { return _function; }
    57     ///\e
    58     int line() const { return _line; }
    59 
    60 
    61     virtual const char* what() const throw() {
    62       try {
    63         std::ostringstream ostr;
    64         ostr << _file << ":" << _line << ": ";
    65         if (_function)
    66           ostr << _function << ": ";
    67         ostr << _message;
    68         if (_assertion)
    69            ostr << " (assertion '" << _assertion << "' failed)";
    70         _message_holder.set(ostr.str());
    71         return ostr.str().c_str();
    72       }
    73       catch(...) {}
    74       if( _message_holder.valid() ) return _message_holder.get().c_str();
    75       return "lemon::AssertionFailedError";
    76     }
    77     virtual ~AssertionFailedError() throw() {}
    78   };
    79 
    80 
    81   inline void assert_fail_log(const char *file, int line,
    82                               const char *function,
    83                               const std::exception& exception,
    84                               const char *assertion)
    85   {
    86     std::cerr << file << ":" << line << ": ";
    87     if (function)
    88       std::cerr << function << ": ";
    89     std::cerr << exception.what();
    90     if (assertion)
    91       std::cerr << " (assertion '" << assertion << "' failed)";
    92     std::cerr << std::endl;
    93   }
    9429
    9530  inline void assert_fail_log(const char *file, int line, const char *function,
     
    10540  }
    10641
    107   inline void assert_fail_log(const char *file, int line, const char *function,
    108                               const std::string& message, const char *assertion)
    109   {
    110     assert_fail_log(file, line, function, message.c_str(), assertion);
    111   }
    112 
    113   inline void assert_fail_abort(const char *file, int line,
    114                                 const char *function,
    115                                 const std::exception& exception,
    116                                 const char *assertion)
    117   {
    118     assert_fail_log(file, line, function, exception, assertion);
    119     std::abort();
    120   }
    121 
    12242  inline void assert_fail_abort(const char *file, int line,
    12343                                const char *function, const char* message,
     
    12848  }
    12949
    130   inline void assert_fail_abort(const char *file, int line,
    131                                 const char *function,
    132                                 const std::string& message,
    133                                 const char *assertion)
    134   {
    135     assert_fail_log(file, line, function, message.c_str(), assertion);
    136     std::abort();
     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    }   
    13760  }
    138 
    139   inline void assert_fail_error(const char *file, int line,
    140                                   const char *function,
    141                                   const std::exception& exception,
    142                                   const char *assertion)
    143   {
    144     throw AssertionFailedError(file, line, function,
    145                                exception.what(), assertion);
    146   }
    147 
    148   inline void assert_fail_error(const char *file, int line,
    149                                   const char *function, const char *message,
    150                                   const char *assertion)
    151   {
    152     throw AssertionFailedError(file, line, function, message, assertion);
    153   }
    154 
    155   inline void assert_fail_error(const char *file, int line,
    156                                   const char *function,
    157                                   const std::string& message,
    158                                   const char *assertion)
    159   {
    160     throw AssertionFailedError(file, line, function, message.c_str(), assertion);
    161   }
    162 
    163   template <typename Exception>
    164   inline void assert_fail_exception(const char *, int, const char *,
    165                                     const Exception& exception,
    166                                     const char *, const std::exception* =
    167                                     static_cast<const Exception*>(0))
    168   {
    169     throw exception;
    170   }
    171 
    172   inline void assert_fail_exception(const char *file, int line,
    173                                     const char *function, const char *message,
    174                                     const char *assertion)
    175   {
    176     throw AssertionFailedError(file, line, function, message, assertion);
    177   }
    178 
    179   inline void assert_fail_exception(const char *file, int line,
    180                                     const char *function,
    181                                     const std::string& message,
    182                                     const char *assertion)
    183   {
    184     throw AssertionFailedError(file, line, function, message.c_str(), assertion);
    185   }
    186 
    187 /// @}
    188 
    18961}
     62
    19063#endif // LEMON_ASSERT_H
    19164
    19265#undef LEMON_ASSERT
    19366#undef LEMON_FIXME
     67#undef LEMON_DEBUG
    19468
    19569#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +               \
    19670  (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
    197   (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +               \
    198   (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +           \
    19971  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
    20072#error "LEMON assertion system is not set properly"
     
    20375#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +              \
    20476     (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
    205      (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +            \
    206      (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +        \
    20777     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
    20878     defined(LEMON_ENABLE_ASSERTS)) &&                  \
    209   defined(LEMON_DISABLE_ASSERTS)
     79  (defined(LEMON_DISABLE_ASSERTS) ||                    \
     80   defined(NDEBUG))
    21081#error "LEMON assertion system is not set properly"
    21182#endif
     
    21889#  undef LEMON_ASSERT_HANDLER
    21990#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
    220 #elif defined LEMON_ASSERT_ERROR
    221 #  undef LEMON_ASSERT_HANDLER
    222 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
    223 #elif defined LEMON_ASSERT_EXCEPTION
    224 #  undef LEMON_ASSERT_HANDLER
    225 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
    22691#elif defined LEMON_ASSERT_CUSTOM
    22792#  undef LEMON_ASSERT_HANDLER
     
    23095#  endif
    23196#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
    232 #elif defined LEMON_ENABLE_ASSERTS
    233 #  undef LEMON_ASSERT_HANDLER
     97#elif defined LEMON_DISABLE_ASSERTS
     98#  undef LEMON_ASSERT_HANDLER
     99#elif defined NDEBUG
     100#  undef LEMON_ASSERT_HANDLER
     101#else
    234102#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
    235 #else
    236 #  undef LEMON_ASSERT_HANDLER
    237 #endif
    238 
     103#endif
    239104
    240105#ifndef LEMON_FUNCTION_NAME
     
    248113/// \brief Macro for assertion with customizable message
    249114///
    250 /// Macro for assertion with customizable message. 
    251 /// \param exp An expression that must be convertible to \c bool.
    252 /// If it is \c false, then an assertion is raised. The concrete
    253 /// behaviour depends on the settings of the assertion system.
    254 /// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
    255 /// a <tt>const std::exception&</tt> parameter, which can be used to
    256 /// provide information about the circumstances of the failed assertion.
    257 ///
    258 /// The assertions are disabled in the default behaviour.
    259 /// You can enable them with the following code:
    260 /// \code
    261 /// #define LEMON_ENABLE_ASSERTS
     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
    262126/// \endcode
    263127/// or with compilation parameters:
    264128/// \code
    265 /// g++ -DLEMON_ENABLE_ASSERTS
    266 /// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
    267 /// \endcode
     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.
    268133///
    269134/// The LEMON assertion system has a wide range of customization
     
    275140/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
    276141///   message to the standard error and continues the execution.
    277 /// - \c LEMON_ASSERT_ABORT This mode is similar to the
    278 ///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
    279 ///   behaviour mode when the assertions are enabled with
    280 ///   \c LEMON_ENABLE_ASSERTS.
    281 /// - \c LEMON_ASSERT_ERROR The assertion throws an
    282 ///   \ref lemon::AssertionFailedError "AssertionFailedError".
    283 ///   If the \c msg parameter is an exception, then the result of the
    284 ///   \ref lemon::Exception::what() "what()" member function is passed
    285 ///   as error message.
    286 /// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
    287 ///   exception, then it raised directly (solving that the exception
    288 ///   can not be thrown polymorphically), otherwise an \ref
    289 ///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
    290 ///   the given parameters.
     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.
    291145/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
    292 ///   functions. Three overloaded functions should be defined with the
    293 ///   following parameter lists:
     146///   function.
    294147///   \code
    295148///     void custom_assert_handler(const char* file, int line, const char* function,
    296149///                                const char* message, const char* assertion);
    297 ///     void custom_assert_handler(const char* file, int line, const char* function,
    298 ///                                const std::string& message, const char* assertion);
    299 ///     void custom_assert_handler(const char* file, int line, const char* function,
    300 ///                                const std::exception& message, const char* assertion);
    301150///   \endcode
    302 ///   The name of the functions should be defined as the \c
     151///   The name of the function should be defined as the \c
    303152///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
    304153///   \code
    305154///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
    306155///   \endcode
    307 ///   Whenever an assertion is occured, one of the custom assertion
    308 ///   handlers is called with appropiate parameters.
     156///   Whenever an assertion is occured, the custom assertion
     157///   handler is called with appropiate parameters.
    309158///
    310159/// The assertion mode can also be changed within one compilation unit.
     
    316165    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
    317166                         LEMON_FUNCTION_NAME,                           \
    318                          msg, #exp), 0)))
    319 
     167                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
    320168
    321169/// \ingroup exceptions
     
    328176///   LEMON_ASSERT(false, msg);
    329177/// \endcode
     178///
     179/// \see LEMON_ASSERT
    330180#  define LEMON_FIXME(msg)                                              \
    331        (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
    332                              "FIXME: " msg, static_cast<const char*>(0)))
     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)))
    333213
    334214#else
     
    337217#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
    338218#    define LEMON_FIXME(msg) (static_cast<void>(0))
     219#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
    339220#  else
    340 #    define LEMON_ASSERT(exp, msg)                 \
    341        (static_cast<void> (!!(exp) ? 0 : (         \
    342          LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
    343                               LEMON_FUNCTION_NAME, \
    344                               msg, #exp), 0)))
    345 #    define LEMON_FIXME(msg) \
     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)                                            \
    346228       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,   \
    347                              "FIXME: " msg,  static_cast<const char*>(0)))
     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
    348242#  endif
    349243
    350244#endif
    351245
    352 
     246#ifdef DOXYGEN
     247
     248
     249#else
     250
     251
     252#endif
     253
     254
Note: See TracChangeset for help on using the changeset viewer.