# HG changeset patch
# User Balazs Dezso <deba@inf.elte.hu>
# Date 1207923654 -7200
# Node ID 407c08a0eae9616db100ccdda51e1babde3ce3a8
# Parent  7b0ce9fb1169c533d2859b8d48bf8586d16fbc91
Exception related solutions removed and new LEMON_DEBUG macro

diff -r 7b0ce9fb1169 -r 407c08a0eae9 lemon/assert.h
--- a/lemon/assert.h	Wed Apr 09 17:19:40 2008 +0100
+++ b/lemon/assert.h	Fri Apr 11 16:20:54 2008 +0200
@@ -27,71 +27,6 @@
 
 namespace lemon {
 
-  /// @{
-
-  ///\e
-  class AssertionFailedError : public LogicError {
-  protected:
-    const char *_assertion;
-    const char *_file;
-    int _line;
-    const char *_function;
-    const char *_message;
-
-    mutable ExceptionMember<std::string> _message_holder;
-  public:
-    ///\e
-    AssertionFailedError(const char *file, int line, const char *function,
-			 const char *msg, const char *assertion = 0) :
-      _assertion(assertion), _file(file), _line(line), 
-      _function(function), _message(msg) {}
-
-    ///\e
-    const char* assertion() const { return _assertion; }
-    ///\e
-    const char* message() const { return _message; }
-    ///\e
-    const char* file() const { return _file; }
-    ///\e
-    const char* function() const { return _function; }
-    ///\e
-    int line() const { return _line; }
-
-
-    virtual const char* what() const throw() {
-      try {
-	std::ostringstream ostr;
-	ostr << _file << ":" << _line << ": ";
-	if (_function)
-	  ostr << _function << ": ";
-	ostr << _message;
-	if (_assertion)
-	   ostr << " (assertion '" << _assertion << "' failed)";
-	_message_holder.set(ostr.str());
-	return ostr.str().c_str();
-      }
-      catch(...) {}
-      if( _message_holder.valid() ) return _message_holder.get().c_str();
-      return "lemon::AssertionFailedError";
-    }
-    virtual ~AssertionFailedError() throw() {}
-  };
-
-
-  inline void assert_fail_log(const char *file, int line,
-			      const char *function,
-			      const std::exception& exception, 
-			      const char *assertion)
-  {
-    std::cerr << file << ":" << line << ": ";
-    if (function)
-      std::cerr << function << ": ";
-    std::cerr << exception.what();
-    if (assertion)
-      std::cerr << " (assertion '" << assertion << "' failed)";
-    std::cerr << std::endl;
-  }
-
   inline void assert_fail_log(const char *file, int line, const char *function,
 			      const char *message, const char *assertion)
   {
@@ -104,21 +39,6 @@
     std::cerr << std::endl;
   }
 
-  inline void assert_fail_log(const char *file, int line, const char *function, 
-			      const std::string& message, const char *assertion)
-  {
-    assert_fail_log(file, line, function, message.c_str(), assertion);
-  }
-
-  inline void assert_fail_abort(const char *file, int line, 
-				const char *function,
-				const std::exception& exception,
-				const char *assertion)
-  {
-    assert_fail_log(file, line, function, exception, assertion);
-    std::abort();
-  }
-
   inline void assert_fail_abort(const char *file, int line,
 				const char *function, const char* message,
 				const char *assertion)
@@ -127,86 +47,37 @@
     std::abort();
   }
 
-  inline void assert_fail_abort(const char *file, int line, 
-				const char *function, 
-				const std::string& message,
-				const char *assertion)
-  {
-    assert_fail_log(file, line, function, message.c_str(), assertion);
-    std::abort();
+  namespace _assert_bits {
+    
+    
+    inline const char* cstringify(const std::string& str) {
+      return str.c_str();
+    }
+
+    inline const char* cstringify(const char* str) {
+      return str;
+    }    
   }
+}
 
-  inline void assert_fail_error(const char *file, int line, 
-				  const char *function,
-				  const std::exception& exception,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, 
-			       exception.what(), assertion);
-  }
-
-  inline void assert_fail_error(const char *file, int line,
-				  const char *function, const char *message,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message, assertion);
-  }
-
-  inline void assert_fail_error(const char *file, int line,
-				  const char *function, 
-				  const std::string& message,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
-  }
-
-  template <typename Exception>
-  inline void assert_fail_exception(const char *, int, const char *,
-				    const Exception& exception,
-				    const char *, const std::exception* = 
-				    static_cast<const Exception*>(0))
-  {
-    throw exception;
-  }
-
-  inline void assert_fail_exception(const char *file, int line,
-				    const char *function, const char *message,
-				    const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message, assertion);
-  }
-
-  inline void assert_fail_exception(const char *file, int line, 
-				    const char *function, 
-				    const std::string& message,
-				    const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
-  }
-
-/// @}
-
-}
 #endif // LEMON_ASSERT_H
 
 #undef LEMON_ASSERT
 #undef LEMON_FIXME
+#undef LEMON_DEBUG
 
 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
   (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
-  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
-  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
   (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
 #error "LEMON assertion system is not set properly"
 #endif
 
 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
      (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
-     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
-     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
      (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
      defined(LEMON_ENABLE_ASSERTS)) &&			\
-  defined(LEMON_DISABLE_ASSERTS)
+  (defined(LEMON_DISABLE_ASSERTS) ||			\
+   defined(NDEBUG))
 #error "LEMON assertion system is not set properly"
 #endif
 
@@ -217,26 +88,20 @@
 #elif defined LEMON_ASSERT_ABORT
 #  undef LEMON_ASSERT_HANDLER
 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
-#elif defined LEMON_ASSERT_ERROR
-#  undef LEMON_ASSERT_HANDLER
-#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
-#elif defined LEMON_ASSERT_EXCEPTION
-#  undef LEMON_ASSERT_HANDLER
-#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
 #elif defined LEMON_ASSERT_CUSTOM
 #  undef LEMON_ASSERT_HANDLER
 #  ifndef LEMON_CUSTOM_ASSERT_HANDLER
 #    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
 #  endif
 #  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
-#elif defined LEMON_ENABLE_ASSERTS
+#elif defined LEMON_DISABLE_ASSERTS
 #  undef LEMON_ASSERT_HANDLER
+#elif defined NDEBUG
+#  undef LEMON_ASSERT_HANDLER
+#else
 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
-#else
-#  undef LEMON_ASSERT_HANDLER
 #endif
 
-
 #ifndef LEMON_FUNCTION_NAME
 #  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
 #endif
@@ -247,24 +112,24 @@
 ///
 /// \brief Macro for assertion with customizable message
 ///
-/// Macro for assertion with customizable message.  
-/// \param exp An expression that must be convertible to \c bool.
-/// If it is \c false, then an assertion is raised. The concrete
-/// behaviour depends on the settings of the assertion system.
-/// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
-/// a <tt>const std::exception&</tt> parameter, which can be used to
-/// provide information about the circumstances of the failed assertion.
+/// Macro for assertion with customizable message.  \param exp An
+/// expression that must be convertible to \c bool.  If it is \c
+/// false, then an assertion is raised. The concrete behaviour depends
+/// on the settings of the assertion system.  \param msg A <tt>const
+/// char*</tt> parameter, which can be used to provide information
+/// about the circumstances of the failed assertion.
 ///
-/// The assertions are disabled in the default behaviour.
-/// You can enable them with the following code:
+/// The assertions are enabled in the default behaviour.
+/// You can disable them with the following code:
 /// \code
-/// #define LEMON_ENABLE_ASSERTS
+/// #define LEMON_DISABLE_ASSERTS
 /// \endcode
 /// or with compilation parameters:
 /// \code
-/// g++ -DLEMON_ENABLE_ASSERTS
-/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
+/// g++ -DLEMON_DISABLE_ASSERTS
+/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
 /// \endcode
+/// The checking is also disabled when the standard macro \c NDEBUG is defined.
 /// 
 /// The LEMON assertion system has a wide range of customization
 /// properties. As a default behaviour the failed assertion prints a
@@ -274,38 +139,22 @@
 ///
 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
 ///   message to the standard error and continues the execution.
-/// - \c LEMON_ASSERT_ABORT This mode is similar to the
-///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
-///   behaviour mode when the assertions are enabled with
-///   \c LEMON_ENABLE_ASSERTS.
-/// - \c LEMON_ASSERT_ERROR The assertion throws an
-///   \ref lemon::AssertionFailedError "AssertionFailedError".
-///   If the \c msg parameter is an exception, then the result of the
-///   \ref lemon::Exception::what() "what()" member function is passed
-///   as error message.
-/// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
-///   exception, then it raised directly (solving that the exception
-///   can not be thrown polymorphically), otherwise an \ref
-///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
-///   the given parameters.
+/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
+///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
+///   behaviour.
 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
-///   functions. Three overloaded functions should be defined with the
-///   following parameter lists:
+///   function.
 ///   \code
 ///     void custom_assert_handler(const char* file, int line, const char* function,
 ///                                const char* message, const char* assertion);
-///     void custom_assert_handler(const char* file, int line, const char* function,
-///                                const std::string& message, const char* assertion);
-///     void custom_assert_handler(const char* file, int line, const char* function,
-///                                const std::exception& message, const char* assertion);
 ///   \endcode
-///   The name of the functions should be defined as the \c
+///   The name of the function should be defined as the \c
 ///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
 ///   \code
 ///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
 ///   \endcode
-///   Whenever an assertion is occured, one of the custom assertion
-///   handlers is called with appropiate parameters.
+///   Whenever an assertion is occured, the custom assertion
+///   handler is called with appropiate parameters.
 ///
 /// The assertion mode can also be changed within one compilation unit.
 /// If the macros are redefined with other settings and the
@@ -315,8 +164,7 @@
   (static_cast<void> (!!(exp) ? 0 : (					\
     LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
 			 LEMON_FUNCTION_NAME,				\
-			 msg, #exp), 0)))
-
+			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
 /// \ingroup exceptions
 ///
@@ -327,26 +175,80 @@
 /// \code
 ///   LEMON_ASSERT(false, msg);
 /// \endcode
+///
+/// \see LEMON_ASSERT 
 #  define LEMON_FIXME(msg)						\
-       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
-			     "FIXME: " msg, static_cast<const char*>(0)))
+  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
+			::lemon::_assert_bits::cstringify(msg),		\
+			static_cast<const char*>(0)))
+
+/// \ingroup exceptions
+///
+/// \brief Macro for internal assertions
+///
+/// Macro for internal assertions, it is used in the library to check
+/// the consistency of results of algorithms, several pre- and
+/// postconditions and invariants. The checking is disabled by
+/// default, but it can be turned on with the macro \c
+/// LEMON_ENABLE_DEBUG.
+/// \code
+/// #define LEMON_ENABLE_DEBUG
+/// \endcode
+/// or with compilation parameters:
+/// \code
+/// g++ -DLEMON_ENABLE_DEBUG
+/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
+/// \endcode
+///
+/// This macro works like the \c LEMON_ASSERT macro, therefore the
+/// current behaviour depends on the settings of \c LEMON_ASSERT
+/// macro.
+///
+/// \see LEMON_ASSERT 
+#  define LEMON_DEBUG(exp, msg)						\
+  (static_cast<void> (!!(exp) ? 0 : (					\
+    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
+			 LEMON_FUNCTION_NAME,				\
+			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
 #else
 
 #  ifndef LEMON_ASSERT_HANDLER
 #    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
 #    define LEMON_FIXME(msg) (static_cast<void>(0))
+#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
 #  else
-#    define LEMON_ASSERT(exp, msg)                 \
-       (static_cast<void> (!!(exp) ? 0 : (         \
-         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
-                              LEMON_FUNCTION_NAME, \
-                              msg, #exp), 0)))
-#    define LEMON_FIXME(msg) \
+#    define LEMON_ASSERT(exp, msg)					\
+       (static_cast<void> (!!(exp) ? 0 : (				\
+        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
+			     LEMON_FUNCTION_NAME,			\
+			     ::lemon::_assert_bits::cstringify(msg),	\
+			     #exp), 0)))
+#    define LEMON_FIXME(msg)						\
        (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
-			     "FIXME: " msg,  static_cast<const char*>(0)))
+			     ::lemon::_assert_bits::cstringify(msg),	\
+			     static_cast<const char*>(0)))
+
+#    if LEMON_ENABLE_DEBUG
+#      define LEMON_DEBUG(exp, msg)
+         (static_cast<void> (!!(exp) ? 0 : (         \
+           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
+                                LEMON_FUNCTION_NAME, \
+				::lemon::_assert_bits::cstringify(msg),	\
+				#exp), 0)))
+#    else
+#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
+#    endif
 #  endif
 
 #endif
 
+#ifdef DOXYGEN
 
+
+#else
+
+
+#endif
+
+
diff -r 7b0ce9fb1169 -r 407c08a0eae9 test/error_test.cc
--- a/test/error_test.cc	Wed Apr 09 17:19:40 2008 +0100
+++ b/test/error_test.cc	Fri Apr 11 16:20:54 2008 +0200
@@ -39,165 +39,21 @@
   LEMON_ASSERT(true, "This is a fault message");
 }
 
-void no_assertion_exception_disable() {
-  LEMON_ASSERT(true, Exception());
-}
-
 void assertion_text_disable() {
   LEMON_ASSERT(false, "This is a fault message");
 }
 
-void assertion_exception_disable() {
-  LEMON_ASSERT(false, Exception());
-}
-
 void fixme_disable() {
   LEMON_FIXME("fixme_disable() is fixme!");
 }
 
 void check_assertion_disable() {
   no_assertion_text_disable();
-  no_assertion_exception_disable();
-  assertion_exception_disable();
   assertion_text_disable();
   fixme_disable();
 }
 #undef LEMON_DISABLE_ASSERTS
 
-
-#define LEMON_ASSERT_ERROR
-#include <lemon/assert.h>
-
-void no_assertion_text_error() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_error() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_error() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_error() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_error() {
-  LEMON_FIXME("fixme_error() is fixme!");
-}
-
-void check_assertion_error() {
-  no_assertion_text_error();
-  no_assertion_exception_error();
-  try {
-    assertion_exception_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    assertion_text_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    fixme_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-}
-#undef LEMON_ASSERT_ERROR
-
-#define LEMON_ASSERT_EXCEPTION
-#include <lemon/assert.h>
-
-void no_assertion_text_exception() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_exception() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_exception() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_exception() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_exception() {
-  LEMON_FIXME("fixme_exception() is fixme!");
-}
-
-void check_assertion_exception() {
-  no_assertion_text_exception();
-  no_assertion_exception_exception();
-  try {
-    assertion_exception_exception();
-    check(false, "Assertion error");
-  } catch (const Exception& e) {
-  }
-
-  try {
-    assertion_text_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    assertion_text_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    fixme_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-}
-#undef LEMON_ASSERT_EXCEPTION
-
-#define LEMON_ASSERT_LOG
-
-#include <lemon/assert.h>
-
-void no_assertion_text_log() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_log() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_log() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_log() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_log() {
-  LEMON_FIXME("fixme_log() is fixme!");
-}
-
-void check_assertion_log() {
-  no_assertion_text_log();
-  no_assertion_exception_log();
-  std::cerr << "The next 3 failure messages are expected: " << std::endl;
-  assertion_exception_log();
-  assertion_text_log();
-  fixme_log();
-  std::cerr << "End of expected error messages" << std::endl;
-}
-#undef LEMON_ASSERT_LOG
-
 #define LEMON_ASSERT_CUSTOM
 
 static int cnt = 0;
@@ -206,17 +62,6 @@
   ++cnt;
 }
 
-void my_assert_handler(const char*, int, const char*, 
-		       const std::exception&, const char*) {
-  ++cnt;
-}
-
-void my_assert_handler(const char*, int, const char*, 
-		       const std::string&, const char*) {
-  ++cnt;
-}
-
-
 #define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
 #include <lemon/assert.h>
 
@@ -224,29 +69,19 @@
   LEMON_ASSERT(true, "This is a fault message");
 }
 
-void no_assertion_exception_custom() {
-  LEMON_ASSERT(true, Exception());
-}
-
 void assertion_text_custom() {
   LEMON_ASSERT(false, "This is a fault message");
 }
 
-void assertion_exception_custom() {
-  LEMON_ASSERT(false, Exception());
-}
-
 void fixme_custom() {
   LEMON_FIXME("fixme_custom() is fixme!");
 }
 
 void check_assertion_custom() {
   no_assertion_text_custom();
-  no_assertion_exception_custom();
-  assertion_exception_custom();
   assertion_text_custom();
   fixme_custom();
-  check(cnt == 3, "The custom assert handler does not work");
+  check(cnt == 2, "The custom assert handler does not work");
 }
 
 #undef LEMON_ASSERT_CUSTOM
@@ -254,9 +89,6 @@
 
 int main() {
   check_assertion_disable();
-  check_assertion_error();
-  check_assertion_exception();
-  check_assertion_log();
   check_assertion_custom();
 
   return 0;