]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Refactor ExceptionBase as well as the Assert and AssertThrow macros
authorMatthias Maier <tamiko@kyomu.43-1.org>
Tue, 16 Apr 2013 14:42:49 +0000 (14:42 +0000)
committerMatthias Maier <tamiko@kyomu.43-1.org>
Tue, 16 Apr 2013 14:42:49 +0000 (14:42 +0000)
git-svn-id: https://svn.dealii.org/trunk@29300 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/include/deal.II/base/exceptions.h
deal.II/source/base/exceptions.cc

index 613252055e5176ca6fd897ac7f8b57436796f80b..e850c4e51e1f7d44292dc078d75c8a51d2a062da 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <deal.II/base/config.h>
 
-#include <exception>
+#include <stdexcept>
 #include <string>
 #include <ostream>
 
@@ -36,9 +36,9 @@ DEAL_II_NAMESPACE_OPEN
  * what can be done with classes derived from it.
  *
  * @ingroup Exceptions
- * @author Wolfgang Bangerth, 1997, extensions 1998
+ * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
  */
-class ExceptionBase : public std::exception
+class ExceptionBase : public std::runtime_error
 {
 public:
   /**
@@ -46,27 +46,13 @@ public:
    */
   ExceptionBase ();
 
-  /**
-   * The constructor takes the file in which the error happened,
-   * the line and the violated condition as well as the name of the
-   * exception class as a <tt>char*</tt> as arguments.
-   */
-  ExceptionBase (const char *file,
-                 int         line,
-                 const char *function,
-                 const char *cond,
-                 const char *exc_name);
-
   /**
    * Copy constructor.
    */
   ExceptionBase (const ExceptionBase &exc);
 
   /**
-   * Destructor. Empty, but needed for the sake of exception
-   * specification, since the base class has this exception
-   * specification and the automatically generated destructor would
-   * have a different one due to member objects.
+   * Destructor.
    */
   virtual ~ExceptionBase () throw();
 
@@ -81,6 +67,11 @@ public:
                    const char *cond,
                    const char *exc_name);
 
+  /**
+   * Get exception name.
+   */
+  const char * get_exc_name() const;
+
   /**
    * Print out the general part of the error information.
    */
@@ -92,18 +83,6 @@ public:
    */
   virtual void print_info (std::ostream &out) const;
 
-
-  /**
-   * Function derived from the base class which allows to pass
-   * information like the line and name of the file where the exception
-   * occurred as well as user information.
-   *
-   * This function is mainly used when using exceptions declared by the
-   * <tt>DeclException*</tt> macros with the <tt>throw</tt> mechanism or
-   * the <tt>AssertThrow</tt> macro.
-   */
-  virtual const char *what () const throw ();
-
   /**
    * Print a stacktrace, if one has been recorded previously, to the
    * given stream.
@@ -112,7 +91,7 @@ public:
 
 protected:
   /**
-   * Name of the file this exception happen in.
+   * Name of the file this exception happens in.
    */
   const char  *file;
 
@@ -151,9 +130,8 @@ protected:
 
 
 
-
 /**
- * In this namespace functions in connection with the Assert and
+ * In this namespace, functions in connection with the Assert and
  * AssertThrow mechanism are declared.
  *
  * @ingroup Exceptions
@@ -172,11 +150,11 @@ namespace deal_II_exceptions
    * which the program runs, so that one can see in which instance of the
    * program the exception occured.
    *
-   * The string pointed to by the argument is copied, so needs not be
+   * The string pointed to by the argument is copied, so doesn't need to be
    * stored after the call to this function.
    *
-   * Previously set additional output is replaced by the argument given
-   * to this function.
+   * Previously set additional output is replaced by the argument given to
+   * this function.
    */
   void set_additional_assert_output (const char *const p);
 
@@ -191,16 +169,15 @@ namespace deal_II_exceptions
   void suppress_stacktrace_in_exceptions ();
 
   /**
-   * Calling this function switches off the use of std::abort() when an
-   * exception is created using the Assert() macro. Instead, the Exception
-   * will be thrown using 'throw', so it can be caught if desired.
-   *  Generally, you want
-   * to abort the execution of a program when Assert() is called, but it
-   * needs to be switched off if you want to log all exceptions created,
-   * or if you want to test if an assertion is working correctly. This is
-   * done for example in regression tests. Please note that some fatal
-   * errors will still call abort(), e.g. when an exception is caught
-   * during exception handling.
+   * Calling this function switches off the use of <tt>std::abort()</tt>
+   * when an exception is created using the Assert() macro. Instead, the
+   * Exception will be thrown using 'throw', so it can be caught if
+   * desired. Generally, you want to abort the execution of a program when
+   * Assert() is called, but it needs to be switched off if you want to log
+   * all exceptions created, or if you want to test if an assertion is
+   * working correctly. This is done for example in regression tests.
+   * Please note that some fatal errors will still call abort(), e.g. when
+   * an exception is caught during exception handling.
    */
   void disable_abort_on_exception ();
 
@@ -216,27 +193,21 @@ namespace deal_II_exceptions
   {
 
     /**
-     * This routine does the main work for the exception generation
-     * mechanism used in the <tt>Assert</tt> macro.
-     *
-     * @ref ExceptionBase
+     * Conditionally abort the program. Depending on whether
+     * disable_abort_on_exception was called, this function either aborts
+     * the program flow by printing an error message and calling
+     * <tt>std::abort()</tt>, or throws @p exc instead.
      */
-    void issue_error_assert (const char *file,
-                             int         line,
-                             const char *function,
-                             const char *cond,
-                             const char *exc_name,
-                             ExceptionBase &e);
-
+    void abort (const ExceptionBase &exc);
 
     /**
      * This routine does the main work for the exception generation
-     * mechanism used in the <tt>AssertThrow</tt> macro.
+     * mechanism used in the <tt>Assert</tt> macro.
      *
      * @ref ExceptionBase
      */
     template <class exc>
-    void issue_error_throw (const char *file,
+    void issue_error_abort (const char *file,
                             int         line,
                             const char *function,
                             const char *cond,
@@ -245,68 +216,57 @@ namespace deal_II_exceptions
     {
       // Fill the fields of the exception object
       e.set_fields (file, line, function, cond, exc_name);
-      throw e;
-    }
 
+      dealii::deal_II_exceptions::internals::abort(e);
+    }
 
     /**
-     * Relay exceptions from the <tt>Assert</tt> macro to the
-     * <tt>__IssueError_Assert</tt> function. Used to convert the last
-     * argument from arbitrary type to ExceptionBase which is not
-     * possible inside the <tt>Assert</tt> macro due to syntactical
-     * difficulties in connection with the way we use the macro and the
-     * declaration of the exception classes.
+     * This routine does the main work for the exception generation
+     * mechanism used in the <tt>AssertThrow</tt> macro.
      *
      * @ref ExceptionBase
      */
     template <class exc>
-    inline
-    void issue_error_assert_1 (const char *file,
-                               int         line,
-                               const char *function,
-                               const char *cond,
-                               const char *exc_name,
-                               exc         e)
+    void issue_error (const char *file,
+                      int         line,
+                      const char *function,
+                      const char *cond,
+                      const char *exc_name,
+                      exc         e)
     {
-      issue_error_assert (file,line,function,cond,exc_name,e);
+      // Fill the fields of the exception object
+      e.set_fields (file, line, function, cond, exc_name);
+      throw e;
     }
 
+  } /*namespace internals*/
 
-    /**
-     * Abort the program. This function is used so that we need not
-     * include <tt>cstdlib</tt> into this file since it is included into all
-     * other files of the library and we would like to keep its include
-     * list as short as possible.
-     */
-    void abort ();
-
-  }
-}
+} /*namespace deal_II_exceptions*/
 
 
 
-#ifdef DEBUG
 /**
  * This is the main routine in the exception mechanism for debug mode
  * error checking. It asserts that a certain condition is fulfilled,
  * otherwise issues an error and aborts the program.
  *
- * See the ExceptionBase class for more information.
+ * See the <tt>ExceptionBase</tt> class for more information.
  *
  * @ingroup Exceptions
- * @author Wolfgang Bangerth, November 1997, extensions 1998
+ * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
  */
-#define Assert(cond, exc)                                           \
-  {                                                                 \
-    if (!(cond))                                                    \
-      ::dealii::deal_II_exceptions::internals::                     \
-      issue_error_assert_1 (__FILE__,                               \
-                            __LINE__,                               \
-                            __PRETTY_FUNCTION__, #cond, #exc, exc); \
+#ifdef DEBUG
+#define Assert(cond, exc)                                                 \
+  {                                                                       \
+    if (!(cond))                                                          \
+      ::dealii::deal_II_exceptions::internals::                           \
+      issue_error_abort (__FILE__,                                        \
+                         __LINE__,                                        \
+                         __PRETTY_FUNCTION__, #cond, #exc, exc);          \
   }
 
 #else
-#define Assert(cond, exc)                                           \
+#define Assert(cond, exc)                                                 \
   { }
 #endif
 
@@ -317,49 +277,32 @@ namespace deal_II_exceptions
  * mode error checking. It assert that a certain condition is
  * fulfilled, otherwise issues an error and aborts the program.
  *
- * On some systems (we only know of DEC Alpha systems running under
- * OSF1 or Linux), the compiler fails to compile the <tt>AssertThrow</tt>
- * macro properly, yielding an internal compiler error. We detect this
- * at configure time. For these cases, the <tt>AssertThrow</tt> macro aborts
- * the program if the assertion is not satisfied. This, however,
- * happens in debug and optimized mode likewise.  Note that in these
- * cases, the meaning of a program changes. In particular, one cannot
- * catch exceptions thrown by <tt>AssertThrow</tt>, but we did not find
- * another way to work around this compiler bug.
- *
  * See the <tt>ExceptionBase</tt> class for more information.
  *
  * @ref ExceptionBase
  * @ingroup Exceptions
- * @author Wolfgang Bangerth, November 1997, extensions 1998
+ * @author Wolfgang Bangerth, 1997, 1998, Matthias Maier, 2013
  */
-#ifndef DISABLE_ASSERT_THROW
-#  ifndef HAVE_BUILTIN_EXPECT
-#    define AssertThrow(cond, exc)                                \
-  {                                                               \
-    if (!(cond))                                                  \
-      ::dealii::deal_II_exceptions::internals::                   \
-      issue_error_throw (__FILE__,                                \
-                         __LINE__,                                \
-                         __PRETTY_FUNCTION__, #cond, #exc, exc);  \
-  }
-#  else /*ifndef HAVE_BUILTIN_EXPECT*/
-#    define AssertThrow(cond, exc)                                \
-  {                                                               \
-    if (__builtin_expect(!(cond), false))                         \
-      ::dealii::deal_II_exceptions::internals::                   \
-      issue_error_throw (__FILE__,                                \
-                         __LINE__,                                \
-                         __PRETTY_FUNCTION__, #cond, #exc, exc);  \
+#ifdef HAVE_BUILTIN_EXPECT
+#define AssertThrow(cond, exc)                                            \
+  {                                                                       \
+    if (__builtin_expect(!(cond), false))                                 \
+      ::dealii::deal_II_exceptions::internals::                           \
+      issue_error (__FILE__,                                              \
+                   __LINE__,                                              \
+                   __PRETTY_FUNCTION__, #cond, #exc, exc);                \
   }
-#  endif /*ifndef HAVE_BUILTIN_EXPECT*/
-#else
-#  define AssertThrow(cond, exc)                                  \
-  {                                                               \
-    if (!(cond))                                                  \
-      ::dealii::deal_II_exceptions::internals::abort ();          \
+
+#else /*ifdef HAVE_BUILTIN_EXPECT*/
+#define AssertThrow(cond, exc)                                            \
+  {                                                                       \
+    if (!(cond))                                                          \
+      ::dealii::deal_II_exceptions::internals::                           \
+      issue_error (__FILE__,                                              \
+                   __LINE__,                                              \
+                   __PRETTY_FUNCTION__, #cond, #exc, exc);                \
   }
-#endif
+#endif /*ifdef HAVE_BUILTIN_EXPECT*/
 
 
 
@@ -371,7 +314,7 @@ namespace deal_II_exceptions
  * @author Wolfgang Bangerth, November 1997
  * @ingroup Exceptions
  */
-#define DeclException0(Exception0)                                \
+#define DeclException0(Exception0)                                        \
   class Exception0 :  public dealii::ExceptionBase {}
 
 
@@ -381,16 +324,16 @@ namespace deal_II_exceptions
  *
  * @ingroup Exceptions
  */
-#define DeclException1(Exception1, type1, outsequence)            \
-  class Exception1 : public dealii::ExceptionBase {               \
-  public:                                                         \
-    Exception1 (const type1 a1) : arg1 (a1) {}                    \
-    virtual ~Exception1 () throw () {}                            \
-    virtual void print_info (std::ostream &out) const {           \
-      out outsequence << std::endl;                               \
-    }                                                             \
-  private:                                                        \
-    const type1 arg1;                                             \
+#define DeclException1(Exception1, type1, outsequence)                    \
+  class Exception1 : public dealii::ExceptionBase {                       \
+  public:                                                                 \
+    Exception1 (const type1 a1) : arg1 (a1) {}                            \
+    virtual ~Exception1 () throw () {}                                    \
+    virtual void print_info (std::ostream &out) const {                   \
+      out outsequence << std::endl;                                       \
+    }                                                                     \
+  private:                                                                \
+    const type1 arg1;                                                     \
   }
 
 
@@ -400,18 +343,18 @@ namespace deal_II_exceptions
  *
  * @ingroup Exceptions
  */
-#define DeclException2(Exception2, type1, type2, outsequence)     \
-  class Exception2 : public dealii::ExceptionBase {               \
-  public:                                                         \
-    Exception2 (const type1 a1, const type2 a2) :                 \
-      arg1 (a1), arg2(a2) {}                                      \
-    virtual ~Exception2 () throw () {}                            \
-    virtual void print_info (std::ostream &out) const {           \
-      out outsequence << std::endl;                               \
-    }                                                             \
-  private:                                                        \
-    const type1 arg1;                                             \
-    const type2 arg2;                                             \
+#define DeclException2(Exception2, type1, type2, outsequence)             \
+  class Exception2 : public dealii::ExceptionBase {                       \
+  public:                                                                 \
+    Exception2 (const type1 a1, const type2 a2) :                         \
+      arg1 (a1), arg2(a2) {}                                              \
+    virtual ~Exception2 () throw () {}                                    \
+    virtual void print_info (std::ostream &out) const {                   \
+      out outsequence << std::endl;                                       \
+    }                                                                     \
+  private:                                                                \
+    const type1 arg1;                                                     \
+    const type2 arg2;                                                     \
   }
 
 
@@ -421,19 +364,19 @@ namespace deal_II_exceptions
  *
  * @ingroup Exceptions
  */
-#define DeclException3(Exception3, type1, type2, type3, outsequence) \
-  class Exception3 : public dealii::ExceptionBase {               \
-  public:                                                         \
-    Exception3 (const type1 a1, const type2 a2, const type3 a3) : \
-      arg1 (a1), arg2(a2), arg3(a3) {}                            \
-    virtual ~Exception3 () throw () {}                            \
-    virtual void print_info (std::ostream &out) const {           \
-      out outsequence << std::endl;                               \
-    }                                                             \
-  private:                                                        \
-    const type1 arg1;                                             \
-    const type2 arg2;                                             \
-    const type3 arg3;                                             \
+#define DeclException3(Exception3, type1, type2, type3, outsequence)      \
+  class Exception3 : public dealii::ExceptionBase {                       \
+  public:                                                                 \
+    Exception3 (const type1 a1, const type2 a2, const type3 a3) :         \
+      arg1 (a1), arg2(a2), arg3(a3) {}                                    \
+    virtual ~Exception3 () throw () {}                                    \
+    virtual void print_info (std::ostream &out) const {                   \
+      out outsequence << std::endl;                                       \
+    }                                                                     \
+  private:                                                                \
+    const type1 arg1;                                                     \
+    const type2 arg2;                                                     \
+    const type3 arg3;                                                     \
   }
 
 
@@ -444,20 +387,20 @@ namespace deal_II_exceptions
  * @ingroup Exceptions
  */
 #define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
-  class Exception4 : public dealii::ExceptionBase {               \
-  public:                                                         \
-    Exception4 (const type1 a1, const type2 a2,                   \
-                const type3 a3, const type4 a4) :                 \
-      arg1 (a1), arg2(a2), arg3(a3), arg4(a4) {}                  \
-    virtual ~Exception4 () throw () {}                            \
-    virtual void print_info (std::ostream &out) const {           \
-      out outsequence << std::endl;                               \
-    }                                                             \
-  private:                                                        \
-    const type1 arg1;                                             \
-    const type2 arg2;                                             \
-    const type3 arg3;                                             \
-    const type4 arg4;                                             \
+  class Exception4 : public dealii::ExceptionBase {                       \
+  public:                                                                 \
+    Exception4 (const type1 a1, const type2 a2,                           \
+                const type3 a3, const type4 a4) :                         \
+      arg1 (a1), arg2(a2), arg3(a3), arg4(a4) {}                          \
+    virtual ~Exception4 () throw () {}                                    \
+    virtual void print_info (std::ostream &out) const {                   \
+      out outsequence << std::endl;                                       \
+    }                                                                     \
+  private:                                                                \
+    const type1 arg1;                                                     \
+    const type2 arg2;                                                     \
+    const type3 arg3;                                                     \
+    const type4 arg4;                                                     \
   }
 
 
@@ -468,25 +411,26 @@ namespace deal_II_exceptions
  * @ingroup Exceptions
  */
 #define DeclException5(Exception5, type1, type2, type3, type4, type5, outsequence) \
-  class Exception5 : public dealii::ExceptionBase {               \
-  public:                                                         \
-    Exception5 (const type1 a1, const type2 a2, const type3 a3,   \
-                const type4 a4, const type5 a5) :                 \
-      arg1 (a1), arg2(a2), arg3(a3), arg4(a4), arg5(a5) {}        \
-    virtual ~Exception5 () throw () {}                            \
-    virtual void print_info (std::ostream &out) const {           \
-      out outsequence << std::endl;                               \
-    }                                                             \
-  private:                                                        \
-    const type1 arg1;                                             \
-    const type2 arg2;                                             \
-    const type3 arg3;                                             \
-    const type4 arg4;                                             \
-    const type5 arg5;                                             \
+  class Exception5 : public dealii::ExceptionBase {                       \
+  public:                                                                 \
+    Exception5 (const type1 a1, const type2 a2, const type3 a3,           \
+                const type4 a4, const type5 a5) :                         \
+      arg1 (a1), arg2(a2), arg3(a3), arg4(a4), arg5(a5) {}                \
+    virtual ~Exception5 () throw () {}                                    \
+    virtual void print_info (std::ostream &out) const {                   \
+      out outsequence << std::endl;                                       \
+    }                                                                     \
+  private:                                                                \
+    const type1 arg1;                                                     \
+    const type2 arg2;                                                     \
+    const type3 arg3;                                                     \
+    const type4 arg4;                                                     \
+    const type5 arg5;                                                     \
   }
 
 #else /*ifndef DOXYGEN*/
 
+// Dummy definitions for doxygen:
 
 /**
  * Declare an exception class derived from ExceptionBase without parameters.
@@ -494,7 +438,7 @@ namespace deal_II_exceptions
  * @author Wolfgang Bangerth, November 1997
  * @ingroup Exceptions
  */
-#define DeclException0(Exception0)                                \
+#define DeclException0(Exception0)                                        \
   static dealii::ExceptionBase& Exception0 ()
 
 
@@ -504,33 +448,33 @@ namespace deal_II_exceptions
  *
  * @ingroup Exceptions
  */
-#define DeclException1(Exception1, type1, outsequence)            \
+#define DeclException1(Exception1, type1, outsequence)                    \
   static dealii::ExceptionBase& Exception1 (type1 arg1) throw (errortext outsequence)
 
 
 /**
- * Declare an exception class derived from ExceptionBase with
- * two additional parameters.
+ * Declare an exception class derived from ExceptionBase with two
+ * additional parameters.
  *
  * @ingroup Exceptions
  */
-#define DeclException2(Exception2, type1, type2, outsequence)     \
+#define DeclException2(Exception2, type1, type2, outsequence)             \
   static dealii::ExceptionBase& Exception2 (type1 arg1, type2 arg2) throw (errortext outsequence)
 
 
 /**
- * Declare an exception class derived from ExceptionBase with
- * three additional parameters.
+ * Declare an exception class derived from ExceptionBase with three
+ * additional parameters.
  *
  * @ingroup Exceptions
  */
-#define DeclException3(Exception3, type1, type2, type3, outsequence) \
+#define DeclException3(Exception3, type1, type2, type3, outsequence)      \
   static dealii::ExceptionBase& Exception3 (type1 arg1, type2 arg2, type3 arg3) throw (errortext outsequence)
 
 
 /**
- * Declare an exception class derived from ExceptionBase with
- * four additional parameters.
+ * Declare an exception class derived from ExceptionBase with four
+ * additional parameters.
  *
  * @ingroup Exceptions
  */
@@ -539,8 +483,8 @@ namespace deal_II_exceptions
 
 
 /**
- * Declare an exception class derived from ExceptionBase with
- * five additional parameters.
+ * Declare an exception class derived from ExceptionBase with five
+ * additional parameters.
  *
  * @ingroup Exceptions
  */
@@ -571,10 +515,9 @@ namespace StandardExceptions
   /**
    * Exception denoting a division by zero.
    *
-   * @note Unfortunately, automatic detection of division by zero
-   * is very hardware dependent and requires severe hacking on some
-   * architectures.
-   * Therefore, this exception is only raised if the test s performed
+   * @note Unfortunately, automatic detection of division by zero is very
+   * hardware dependent and requires severe hacking on some architectures.
+   * Therefore, this exception is only raised if the test is performed
    * explicitly.
    */
   DeclException0 (ExcDivideByZero);
@@ -582,9 +525,9 @@ namespace StandardExceptions
   /**
    * Exception raised if a number is not finite.
    *
-   * This exception should be used to catch infinite or not a number results
-   * of arithmetic operations that do not result from a division by zero
-   * (use ExcDivideByZero for those).
+   * This exception should be used to catch infinite or not a number
+   * results of arithmetic operations that do not result from a division by
+   * zero (use ExcDivideByZero for those).
    */
   DeclException0 (ExcNumberNotFinite);
 
@@ -770,10 +713,10 @@ namespace StandardExceptions
 
   /**
    * This exception works around a design flaw in the
-   * <tt>DeclException0</tt> macro: exceptions desclared through
+   * <tt>DeclException0</tt> macro: exceptions declared through
    * DeclException0 do not allow one to specify a message that is displayed
-   * when the exception is raised, as opposed to the other exceptions
-   * which allow to show a text along with the given parameters.
+   * when the exception is raised, as opposed to the other exceptions which
+   * allow to show a text along with the given parameters.
    *
    * When throwing this exception, you can give a message as a
    * <tt>std::string</tt> as argument to the exception that is then
index f6e97c86a9b8ef3397497a2468e55a83a64134b6..f7f5582a3b815a23be9ad8630ce522467628aa4b 100644 (file)
@@ -40,8 +40,6 @@ namespace deal_II_exceptions
     additional_assert_output = p;
   }
 
-
-
   bool show_stacktrace = true;
 
   void suppress_stacktrace_in_exceptions ()
@@ -49,30 +47,25 @@ namespace deal_II_exceptions
     show_stacktrace = false;
   }
 
-
   bool abort_on_exception = true;
 
   void disable_abort_on_exception ()
   {
     abort_on_exception = false;
   }
+
 }
 
 
 
 ExceptionBase::ExceptionBase ()
   :
-  file(""), line(0), function(""), cond(""), exc(""),
-  stacktrace (0),
-  n_stacktrace_frames (0)
-{}
-
-
-
-ExceptionBase::ExceptionBase (const char *f, const int l, const char *func,
-                              const char *c, const char *e)
-  :
-  file(f), line(l), function(func), cond(c), exc(e),
+  std::runtime_error(""),
+  file(""),
+  line(0),
+  function(""),
+  cond(""),
+  exc(""),
   stacktrace (0),
   n_stacktrace_frames (0)
 {}
@@ -81,11 +74,13 @@ ExceptionBase::ExceptionBase (const char *f, const int l, const char *func,
 
 ExceptionBase::ExceptionBase (const ExceptionBase &exc)
   :
-  std::exception (exc),
-  file(exc.file), line(exc.line),
-  function(exc.function), cond(exc.cond), exc(exc.exc),
-  // don't copy stacktrace to avoid double de-allocation problem
-  stacktrace (0),
+  std::runtime_error (exc),
+  file(exc.file),
+  line(exc.line),
+  function(exc.function),
+  cond(exc.cond),
+  exc(exc.exc),
+  stacktrace (0), // don't copy stacktrace to avoid double de-allocation problem
   n_stacktrace_frames (0)
 {}
 
@@ -103,7 +98,7 @@ ExceptionBase::~ExceptionBase () throw ()
 
 
 void ExceptionBase::set_fields (const char *f,
-                                const int l,
+                                const int  l,
                                 const char *func,
                                 const char *c,
                                 const char *e)
@@ -120,6 +115,60 @@ void ExceptionBase::set_fields (const char *f,
   n_stacktrace_frames = backtrace(array, 25);
   stacktrace = backtrace_symbols(array, n_stacktrace_frames);
 #endif
+
+  // build up a string with the error message...
+
+  std::ostringstream converter;
+
+  converter << std::endl
+            << "--------------------------------------------------------"
+            << std::endl;
+  // print out general data
+  print_exc_data (converter);
+  // print out exception specific data
+  print_info (converter);
+  print_stack_trace (converter);
+
+  if (!deal_II_exceptions::additional_assert_output.empty())
+    converter << "--------------------------------------------------------"
+              << std::endl
+              << deal_II_exceptions::additional_assert_output
+              << std::endl;
+
+  converter << "--------------------------------------------------------"
+            << std::endl;
+
+  // ... and setup the final error message with it:
+  static_cast<std::runtime_error &>(*this) = std::runtime_error(converter.str());
+}
+
+
+
+const char * ExceptionBase::get_exc_name () const
+{
+  return exc;
+}
+
+
+
+void ExceptionBase::print_exc_data (std::ostream &out) const
+{
+  out << "An error occurred in line <" << line
+      << "> of file <" << file
+      << "> in function" << std::endl
+      << "    " << function << std::endl
+      << "The violated condition was: "<< std::endl
+      << "    " << cond << std::endl
+      << "The name and call sequence of the exception was:" << std::endl
+      << "    " << exc  << std::endl
+      << "Additional Information: " << std::endl;
+}
+
+
+
+void ExceptionBase::print_info (std::ostream &out) const
+{
+  out << "(none)" << std::endl;
 }
 
 
@@ -132,7 +181,6 @@ void ExceptionBase::print_stack_trace (std::ostream &out) const
   if (deal_II_exceptions::show_stacktrace == false)
     return;
 
-
   // if there is a stackframe stored, print it
   out << std::endl;
   out << "Stacktrace:" << std::endl
@@ -223,179 +271,34 @@ void ExceptionBase::print_stack_trace (std::ostream &out) const
 }
 
 
-void ExceptionBase::print_exc_data (std::ostream &out) const
-{
-  out << "An error occurred in line <" << line
-      << "> of file <" << file
-      << "> in function" << std::endl
-      << "    " << function << std::endl
-      << "The violated condition was: "<< std::endl
-      << "    " << cond << std::endl
-      << "The name and call sequence of the exception was:" << std::endl
-      << "    " << exc  << std::endl
-      << "Additional Information: " << std::endl;
-  // Additionally, leave a trace in deallog if we do not stop here
-  if (deal_II_exceptions::abort_on_exception == false)
-    deallog << exc << std::endl;
-}
-
-
-void ExceptionBase::print_info (std::ostream &out) const
-{
-  out << "(none)" << std::endl;
-}
-
-
-// TODO !
-const char *ExceptionBase::what () const throw ()
-{
-  // if we say that this function does not throw exceptions, we better make
-  // sure it does not
-  try
-    {
-      // have a place where to store the description of the exception as a
-      // char *
-      //
-      // this thing obviously is not multi-threading safe, but we don't
-      // care about that for now
-      //
-      // we need to make this object static, since we want to return the
-      // data stored in it and therefore need a lifetime which is longer
-      // than the execution time of this function
-      static std::string description;
-      // convert the messages printed by the exceptions into a std::string
-      std::ostringstream converter;
-
-      converter << "--------------------------------------------------------"
-                << std::endl;
-      // put general info into the std::string
-      print_exc_data (converter);
-      // put in exception specific data
-      print_info (converter);
-
-      print_stack_trace (converter);
-
-      converter << "--------------------------------------------------------"
-                << std::endl;
-
-      description = converter.str();
-
-      return description.c_str();
-    }
-  catch (std::exception &exc)
-    {
-      std::cerr << "*** Exception encountered in exception handling routines ***"
-                << std::endl
-                << "*** Message is "   << std::endl
-                << exc.what ()         << std::endl
-                << "*** Aborting! ***" << std::endl;
-
-      std::abort ();
-    }
-  catch (...)
-    {
-      std::cerr << "*** Exception encountered in exception handling routines ***"
-                << std::endl
-                << "*** Aborting! ***" << std::endl;
-
-      std::abort ();
-    }
-  return 0;
-}
-
-
 
 namespace deal_II_exceptions
 {
   namespace internals
   {
 
-    /**
-     * Number of exceptions dealt with so far. Zero at program start.
-     * Messages are only displayed if the value is zero.
-     */
-    unsigned int n_treated_exceptions;
-    ExceptionBase *last_exception;
-
-
-    void issue_error_assert (const char *file,
-                             int         line,
-                             const char *function,
-                             const char *cond,
-                             const char *exc_name,
-                             ExceptionBase &e)
+    void abort (const ExceptionBase &exc)
     {
-      // fill the fields of the exception object
-      e.set_fields (file, line, function, cond, exc_name);
-
-      // if no other exception has been displayed before, show this one
-      if (n_treated_exceptions == 0)
+      if(dealii::deal_II_exceptions::abort_on_exception)
         {
-          std::cerr << "--------------------------------------------------------"
-                    << std::endl;
-          // print out general data
-          e.print_exc_data (std::cerr);
-          // print out exception specific data
-          e.print_info (std::cerr);
-          e.print_stack_trace (std::cerr);
-          std::cerr << "--------------------------------------------------------"
-                    << std::endl;
-
-          // if there is more to say, do so
-          if (!additional_assert_output.empty())
-            std::cerr << additional_assert_output << std::endl;
+          std::cerr << exc.what() << std::endl;
+          std::abort();
         }
       else
         {
-          // if this is the first follow-up message, display a message that
-          // further exceptions are suppressed
-          if (n_treated_exceptions == 1)
-            std::cerr << "******** More assertions fail but messages are suppressed! ********"
-                      << std::endl;
-        };
-
-      // increase number of treated exceptions by one
-      n_treated_exceptions++;
-      last_exception = &e;
-
-
-      // abort the program now since something has gone horribly wrong.
-      // however, there is one case where we do not want to do that, namely
-      // when another exception, possibly thrown by AssertThrow is active,
-      // since in that case we will not come to see the original exception.
-      // in that case indicate that the program is not aborted due to this
-      // reason.
-      if (std::uncaught_exception() == true)
-        {
-          // only display message once
-          if (n_treated_exceptions <= 1)
-            std::cerr << "******** Program is not aborted since another exception is active! ********"
-                      << std::endl;
-        }
-      else if (deal_II_exceptions::abort_on_exception == true)
-        std::abort ();
-      else
-        {
-          --n_treated_exceptions;
-          throw e;
+          throw exc;
         }
     }
 
+  } /*namespace internals*/
+} /*namespace deal_II_exceptions*/
 
 
-    void abort ()
-    {
-      if (deal_II_exceptions::abort_on_exception == true)
-        std::abort ();
-    }
-
-  }
-
-}
 
 DEAL_II_NAMESPACE_CLOSE
 
 
+
 // Newer versions of gcc have a very nice feature: you can set a verbose
 // terminate handler, that not only aborts a program when an exception is
 // thrown and not caught somewhere, but before aborting it prints that an

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.