]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Adapt programs to the changes in the exception handling mechanisms (run-time checks...
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 13 Dec 1998 20:59:22 +0000 (20:59 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 13 Dec 1998 20:59:22 +0000 (20:59 +0000)
git-svn-id: https://svn.dealii.org/trunk@706 0785d39b-7218-0410-832d-ea1e28bc413d

16 files changed:
deal.II/base/include/base/exceptions.h
deal.II/base/include/base/parameter_handler.h
deal.II/base/include/base/tensor_base.h
deal.II/base/source/parameter_handler.cc
deal.II/deal.II/include/dofs/dof_constraints.h
deal.II/deal.II/include/grid/tria.h
deal.II/deal.II/include/numerics/data_io.h
deal.II/deal.II/source/dofs/dof_constraints.cc
deal.II/deal.II/source/grid/tria.cc
deal.II/deal.II/source/numerics/data_io.cc
deal.II/lac/include/lac/dfmatrix.h
deal.II/lac/include/lac/dsmatrix.h
deal.II/lac/include/lac/dvector.h
deal.II/lac/source/dfmatrix.cc
deal.II/lac/source/dsmatrix.cc
deal.II/lac/source/dvector.cc

index fef9d1119df2826c923f0fb7d070bd5b66b8a6c6..e701c61d79f7f1e798135b014d24fd931d595a39 100644 (file)
 
 
 
-
 #ifndef __GNUC__
 #  define __PRETTY_FUNCTION__ "(unknown)"
 #endif
 
-                                /**
-                                 *  This class should be used as a base class for
-                                 *  all exception classes. Do not use its methods
-                                 *  and variables directly since the interface
-                                 *  and mechanism may be subject to change. Rather
-                                 *  create new exception classes using the
-                                 *  #DeclException# macro family.
-                                 *
-                                 *  @see Assert
-                                 *  @see DeclException0
-                                 *  @author Wolfgang Bangerth, November 1997
-                                 */
+
+/**
+ *  This class should be used as a base class for
+ *  all exception classes. Do not use its methods
+ *  and variables directly since the interface
+ *  and mechanism may be subject to change. Rather
+ *  create new exception classes using the
+ *  #DeclException# macro family.
+ *
+ *
+ *  \section{General overview of the exception handling mechanism in #deal.II#}
+ *
+ *  The error handling mechanism in #deal.II# is generally used in two ways.
+ *  The first uses error checking in debug mode only and is useful for programs
+ *  which are not fully tested. When the program shows no error anymore, one may
+ *  switch off error handling and get better performance by this, since checks
+ *  for errors are done quite frequently in the library (a typical speed up is
+ *  a factor of four!). This mode of exception generation is most useful for
+ *  internal consistency checks such as range checking or checking of the
+ *  validity of function arguments. Errors of this kind usually are programming
+ *  errors and the program should abort with as detailed a message as possible,
+ *  including location and reason for the generation of the exception.
+ *
+ *  The second mode is for error checks which should always be on, such as for
+ *  I/O errors, failing memory requests and the like. It does not make much
+ *  sense to turn this mode off, since this kind of errors may happen in tested
+ *  and untested programs likewise. Exceptions of this kind do not terminate the
+ *  program, rather they throw exceptions in the #C++# manner, allowing the
+ *  program to catch them and eventually do something about it. As it may be
+ *  useful to have some information printed out if an exception could not be
+ *  handled properly, additional information is passed along as for the first
+ *  mode. The latter makes it necessary to provide a family of macros which
+ *  enter this additional information into the exception class; this could
+ *  in principle be done by the programmer himself each time by hand, but since
+ *  the information can be obtained automatically, a macro is provided for
+ *  this.
+ *
+ *  Both modes use exception classes, which need to have special features
+ *  additionally to the #C++# standard's #exception# class. Such a class
+ *  is declared by the following lines of code:
+ *   \begin{verbatim}
+ *     DeclException2 (ExcDomain, int, int,
+ *                     << "Index= " << arg1 << "Upper Bound= " << arg2);
+ *  \end{verbatim}
+ *  This declares an exception class named #ExcDomain#, which
+ *  has two variables as additional information (named
+ *  #arg1# and #arg2# by default) and which outputs the
+ *  given sequence (which is appended to an #ostream#
+ *  variable's name, thus the weird syntax). There are
+ *  other #DeclExceptionN# macros for exception classes
+ *  with more or no parameters. It is proposed to let start
+ *  the name of all exceptions by #Exc...# and to declare them locally to
+ *  the class it is to be used in. Declaring exceptions globally is possible
+ *  but pollutes the global namespace, is less readable and thus unnecessary.
+ *
+ *  Since exception classes are declared the same way for both modes of error
+ *  checking, it is possible to use an exception declared through the
+ *  #DeclExceptionN(...)# macro family in both modes; there is no need to
+ *  declare different classes for each of these.
+ *
+ *
+ *  \section{Use of the debug mode exceptions}
+ *
+ *  To use the exception mechanism for debug mode error checking, write lines
+ *  like the following in your source code:
+ *  \begin{verbatim}
+ *    Assert (n<dim, ExcDomain(n,dim));
+ *  \end{verbatim}
+ *  which by macro expansion does the following:
+ *  \begin{verbatim}
+ *    #ifdef DEBUG
+ *        if (!cond)
+ *              issue error of class ExcDomain(n,dim)
+ *    #else
+ *        do nothing
+ *    #endif
+ *  \end{verbatim}
+ *  i.e. it issues an error only if the preprocessor variable
+ *  #DEBUG# is set and if the given condition (in this case
+ *  #n<dim# is violated.
+ *
+ *  If the exception was declared using the #DeclException0 (...)#
+ *  macro, i.e. without any additional parameters, its name has
+ *  nonetheless to be given with parentheses:
+ *  #Assert (i>m, ExcSomewhat());#
+ *
+ *  \subsection{How it works internally}
+ *  If the #DEBUG# preprocessor directive is set, the call #Assert (cond, exc);#
+ *  is converted by the preprocessor into the sequence
+ *  \begin{verbatim}
+ *    if (!(cond))
+ *      __IssueError_Assert (__FILE__,
+ *                           __LINE__,
+ *                           __PRETTY_FUNCTION__,
+ *                           #cond,
+ *                           #exc,
+ *                           &exc);
+ *  \end{verbatim}
+ *  i.e. if the given condition is violated, then the file and
+ *  line in which the exception occured as well as
+ *  the condition itself and the call sequence of the
+ *  exception object is transferred. Additionally an object
+ *  of the form given by #exc# is created (this is normally an
+ *  unnamed object like in #ExcDomain (n, dim)# of class
+ *  #ExcDomain#) and transferred to the #__IssueError_Assert#
+ *  function.
+ *
+ *  #__PRETTY__FUNCTION__# is a macro defined only by the GNU CC
+ *  compiler and gives the name of the function. If another compiler
+ *  is used, we set #__PRETTY_FUNCTION__ = "(unknown)"#.
+ *
+ *  In #__IssueError# the given data
+ *  is transferred into the #exc# object by calling the
+ *  #SetFields# function; after that, the general error info
+ *  is printed onto #cerr# using the #PrintError# function of
+ *  #exc# and finally the exception specific data is printed
+ *  using the user defined function #PrintError# (which is
+ *  normally created using the #DeclException (...)# macro
+ *  family.
+ *
+ *  After printing all this information, #abort()# is called.
+ *  This terminates the program, which is the right thing to do for
+ *  this kind of error checking since it is used to detect programming
+ *  errors rather than run-time errors; a program can, by definition,
+ *  not recover from programming errors.
+ *
+ *  If the preprocessor variable #DEBUG# is not set, then nothing
+ *  happens, i.e. the #Assert# macro is expanded to #(void) 0;#.
+ *
+ *  Sometimes, there is no useful condition for an exception other
+ *  than that the program flow should not have reached a certain point,
+ *  e.g. a #default# section of a #switch# statement. In this case,
+ *  raise the exception by the following construct:
+ *  \begin{verbatim}
+ *    Assert (false, ExcInternalError());
+ *  \end{verbatim}
+ *
+ *
+ *  \section{Use of run-time exceptions}
+ *
+ *  For this mode, the standard #C++# #throw# and #catch# concept exists. We
+ *  want to keep to this, but want to extend it a bit. In general, the
+ *  structure is the same, i.e. you normally raise and exception by
+ *  \begin{verbatim}
+ *    if (!cond)
+ *      throw ExcSomething();
+ *  \end{verbatim}
+ *  and catch it using the statement
+ *  \begin{verbatim}
+ *    try {
+ *      do_something ();
+ *    }
+ *    catch (exception &e) {
+ *      cerr << "Exception occured:" << endl
+ *           << e.what ()
+ *           << endl;
+ *      do_something_to_reciver ();
+ *    };
+ *  \end{verbatim}
+ *  #exception# is a standard #C++# class providing basic functionality for
+ *  exceptions, such as the virtual function #what()# which returns some
+ *  information on the exception itself. This information is useful if an
+ *  exception can't be handled properly, in which case as precise a description
+ *  as possible should be printed.
+ *
+ *  The problem here is that to get significant and useful information out
+ *  of #what()#, it is necessary to overload this function in out exception
+ *  class and call the #throw# operator with additional arguments to the
+ *  exception class. The first thing, overloading the #what# function is
+ *  done using the #DeclExceptionN# macros, but putting the right information,
+ *  which is the same as explained above for the #Assert# expansion, requires
+ *  some work if one would want to write it down each time:
+ *  \begin{verbatim}
+ *    if (!cond)
+ *      {
+ *        ExcSomething e(additional information);
+ *        e.SetFields (__FILE__, __LINE__, __PRETTY_FUNCTION__,
+ *                     "condition as a string",
+ *                     "name of condition as a string");
+ *        throw e;
+ *      };
+ *  \end{verbatim}
+ *
+ *  For this purpose, the macro #AssertThrow# was invented. It does mainly
+ *  the same job as does the #Assert# macro, but it does not kill the
+ *  program, it rather throws an exception as shown above. The mode of usage
+ *  is
+ *  \begin{verbatim}
+ *    AssertThrow (cond, ExcSomething(additional information));
+ *  \end{verabtim}
+ *  The condition to be checked is incorporated into the macro in order to
+ *  allow passing the violated condition as a string. The expansion of the
+ *  #AssertThrow# macro is not affected by the #DEBUG# preprocessor variable.
+ *
+ *
+ *  \section{Description of the #DeclExceptionN# macro family}
+ *
+ *  Declare an exception class without any additional parameters.
+ *  There is a whole family of #DeclException?# macros
+ *  where #?# is to be replaced by the number of additional
+ *  parameters (0 to 5 presently).
+ *  
+ *  The syntax is as follows:
+ *  \begin{verbatim}
+ *    DeclException2 (ExcDomain,
+ *                    int,
+ *                    int,
+ *                    << " i=" << arg1 << ", m=" << arg2);
+ *  \end{verbatim}
+ *  The first is the name of the exception class to be created.
+ *  The next arguments are the types of the parameters (in this
+ *  case there are two type names needed) and finally the output
+ *  sequence with which you can print additional information.
+ *  
+ *  The syntax of the output sequence is a bit weird but gets
+ *  clear once you see how this macro is defined:
+ *  \begin{verbatim}
+ *  class name : public ExceptionBase {
+ *    public:
+ *      name (const type1 a1, const type2 a2) :
+ *                     arg1 (a1), arg2(a2) {};
+ *      virtual void PrintInfo (ostream &out) const {
+ *        out outsequence << endl;
+ *      };
+ *    private:
+ *      type1 arg1;
+ *      type2 arg2;
+ *  };
+ *  \end{verbatim}
+ *   
+ *  If declared as specified, you can later use this exception class
+ *  in the following manner:
+ *  \begin{verbatim}
+ *    int i=5;
+ *    int m=3;
+ *    Assert (i<m, MyExc2(i,m));
+ *  \end{verbatim}
+ *  and the output if the condition fails will be
+ *  \begin{verbatim}
+ *    --------------------------------------------------------
+ *    An error occurred in line <301> of file <exc-test.cc>.
+ *    The violated condition was: 
+ *      i<m
+ *    The name and call sequence of the exception was:
+ *      MyExc2(i,m)
+ *    Additional Information: 
+ *      i=5, m=3
+ *    --------------------------------------------------------
+ *  \end{verbatim}
+ *  
+ *  Obviously for the #DeclException0(name)# macro, no types and
+ *  also no output sequence is allowed.
+ *
+ *
+ *  @author Wolfgang Bangerth, November 1997, extensions 1998
+ */
 class ExceptionBase : public exception {
   public:
-    ExceptionBase () :
-                   file(""), line(0), function(""), cond(""), exc("")  {};
+                                    /**
+                                     * Default constructor.
+                                     */
+    ExceptionBase ();
+    
                                     /**
                                      *  The constructor takes the file in which the
                                      *  error happened, the line and the violated
@@ -38,33 +284,8 @@ class ExceptionBase : public exception {
                                      *  exception class as a #char*# as arguments.
                                      */
     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) {};
-
-                                    /**
-                                     * Copy constructor; don't know why, but
-                                     * gcc 2.8 likes to see this one, so we
-                                     * put it here.
-                                     */
-    ExceptionBase (const ExceptionBase &e) :
-                   exception(e),
-                   file(e.file), line(e.line), function(e.function),
-                   cond(e.cond), exc(e.exc) {};
+                  const char* c, const char *e);
 
-                                    /**
-                                     * Copy operator; don't know why, but
-                                     * gcc 2.8 likes to see this one, so we
-                                     * put it here.
-                                     */
-    ExceptionBase & operator = (const ExceptionBase &e) {
-      file     = e.file;
-      line     = e.line;
-      function = e.function;
-      cond     = e.cond;
-      exc      = e.exc;
-      return *this;
-    };
-    
                                     /**
                                      *  Set the file name and line of where the
                                      *  exception appeared as well as the violated
@@ -75,42 +296,20 @@ class ExceptionBase : public exception {
                    const int l,
                    const char *func,
                    const char *c,
-                   const char *e) {
-      file = f;
-      line = l;
-      function = func;
-      cond = c;
-      exc  = e;
-    };
+                   const char *e);
+    
                                     /**
                                      *  Print out the general part of the error
                                      *  information.
                                      */
-    void PrintExcData (ostream &out) const {
-      out << "An error occurred in line <" << line
-         << "> of file <" << file
-         << "> in function" << endl
-         << "    " << function << endl
-         << "The violated condition was: "<< endl
-         << "    " << cond << endl
-         << "The name and call sequence of the exception was:" << endl
-         << "    " << exc  << endl
-         << "Additional Information: " << endl;
-    };
+    void PrintExcData (ostream &out) const;
 
                                     /**
                                      *  Print more specific information about the
                                      *  exception which occured. Overload this
                                      *  function in your own exception classes.
-                                     *  Since we use templates rather than derivation
-                                     *  information, we need not declare this
-                                     *  function as #virtual# and thus avoid problems
-                                     *  with virtual functions in classes in which
-                                     *  all functions are declared inline.
                                      */
-    void PrintInfo (ostream &out) const {
-      out << "(none)" << endl;
-    };
+    virtual void PrintInfo (ostream &out) const;
 
     
                                     /**
@@ -123,142 +322,108 @@ class ExceptionBase : public exception {
                                      *  This function is mainly used when using
                                      *  exceptions declared by the
                                      *  #DeclException*# macros with the #throw#
-                                     *  mechanism or the #Assert_or_Throw# macro.
+                                     *  mechanism or the #AssertThrow# macro.
                                      */
-//    virtual const char * what () const;
+    virtual const char * what () const;
 
-    
-    const char *file;
-    int         line;
-    const char *function;
-    const char *cond;
-    const char *exc;
+  protected:
+                                    /**
+                                     * Name of the file this exception happen in.
+                                     */
+    const char  *file;
+
+                                    /**
+                                     * Line number in this file.
+                                     */
+    unsigned int line;
+
+                                    /**
+                                     * Name of the function, pretty printed.
+                                     */
+    const char  *function;
+
+                                    /**
+                                     * The violated condition, as a string.
+                                     */
+    const char  *cond;
+
+                                    /**
+                                     * Name of the exception and call sequence.
+                                     */
+    const char  *exc;
 };
 
 
-                                /**
-                                 *  This routine does the main work for the
-                                 *  exception generation mechanism.
-                                 *
-                                 *  @see Assert
-                                 */
+
+/**
+ *  This routine does the main work for the
+ *  exception generation mechanism used in the
+ *  #Assert# macro.
+ *
+ *  @see ExceptionBase
+ */
 template <class exc>
-void __IssueError (const char *file,
-                  int         line,
-                  const char *function,
-                  const char *cond,
-                  const char *exc_name,
-                  exc         e) {
+void __IssueError_Assert (const char *file,
+                         int         line,
+                         const char *function,
+                         const char *cond,
+                         const char *exc_name,
+                         exc         e) {
                                   // Fill the fields of the exception object
-      e.SetFields (file, line, function, cond, exc_name);
-      cerr << "--------------------------------------------------------"
-          << endl;
-                                      // print out general data
-      e.PrintExcData (cerr);
-                                      // print out exception specific data
-      e.PrintInfo (cerr);
-      cerr << "--------------------------------------------------------"
-          << endl;
-      
-      abort ();
-    };
+  e.SetFields (file, line, function, cond, exc_name);
+  cerr << "--------------------------------------------------------"
+       << endl;
+                                  // print out general data
+  e.PrintExcData (cerr);
+                                  // print out exception specific data
+  e.PrintInfo (cerr);
+  cerr << "--------------------------------------------------------"
+       << endl;
+  
+  abort ();
+};
+
+
+
+/**
+ *  This routine does the main work for the
+ *  exception generation mechanism used in the
+ *  #AssertThrow# macro.
+ *
+ *  @see ExceptionBase
+ */
+template <class exc>
+void __IssueError_Throw (const char *file,
+                        int         line,
+                        const char *function,
+                        const char *cond,
+                        const char *exc_name,
+                        exc         e) {
+                                  // Fill the fields of the exception object
+  e.SetFields (file, line, function, cond, exc_name);
+  throw e;
+};
+
 
 
     
 #ifdef DEBUG  ////////////////////////////////////////
 
 /**
-    This is the main routine in the exception mechanism.
-    Use it in the following way: declare an exception
-    class using the #DeclException# macros (see there),
-    for example
-    \begin{verbatim}
-      DeclException2 (ExcDomain, int, int,
-                      << "Index= " << arg1 << "Upper Bound= " << arg2);
-    \end{verbatim}
-    to declare an exception class named #ExcDomain#, which
-    has two variables as additional information (named
-    #arg1# and #arg2# by default) and which outputs the
-    given sequence (which is appended to an #ostream#
-    variable's name, thus the weird syntax). There are
-    other #DeclExceptionN# macros for exception classes
-    with more or no parameters. It is proposed to let start
-    the name of all exceptions by #Exc...#.
-
-    In your source code write lines like
-    \begin{verbatim}
-      Assert (n<dim, ExcDomain(n,dim));
-    \end{verbatim}
-    which does the following:
-    \begin{verbatim}
-      #ifdef DEBUG
-          if (!cond)
-                issue error of class ExcDomain(n,dim)
-      #else
-          do nothing
-      #endif
-    \end{verbatim}
-    i.e. it issues an error only if the preprocessor variable
-    #DEBUG# is set and if the given condition (in this case
-    #n<dim# is violated.
-
-    If the exception was declared using the #DeclException0 (...)#
-    macro, i.e. without any additional parameters, its name has
-    nonetheless to be given with parentheses:
-    #Assert (i>m, ExcSomewhat());#
-
-    {\bf How it works internally:}
-    The call #Assert (cond, exc);#
-    is converted by the preprocessor into the sequence
-    \begin{verbatim}
-      if (!(cond))
-        __IssueError (__FILE__,
-                      __LINE__,
-                      __PRETTY_FUNCTION__,
-                      #cond,
-                      #exc,
-                      &exc);
-    \end{verbatim}
-    i.e. if the given condition is violated, then the file and
-    line in which the exception occured as well as
-    the condition itself and the call sequence of the
-    exception object is transferred. Additionally an object
-    of the form given by #exc# is created (this is normally an
-    unnamed object like in #ExcDomain (n, dim)# of class
-    #ExcDomain#) and transferred to the #__IssueError#
-    function.
-
-    #__PRETTY__FUNCTION__# is a macro defined only by the GNU CC
-    compiler and gives the name of the function. If another compiler
-    is used, we set #__PRETTY_FUNCTION__ = "(unknown)"#.
-
-    In #__IssueError# the given data
-    is transferred into the #exc# object by calling the
-    #SetFields# function; after that, the general error info
-    is printed onto #cerr# using the #PrintError# function of
-    #exc# and finally the exception specific data is printed
-    using the user defined function #PrintError# (which is
-    normally created using the #DeclException (...)# macro
-    family.
-
-    After printing all this information, #abort()# is called.
-    This may in future versions be replaced by calling
-    #throw exc;#.
-
-    If the preprocessor variable #DEBUG# is not set, then nothing
-    happens, i.e. the macro is expanded to #(void) 0;#.
-
-    @memo Assert that a certain condition is fulfilled, otherwise
-    issue an error and abort the program.
-    
-    @see DeclException0
-    @author Wolfgang Bangerth, November 1997
-    */
-#define Assert(cond, exc)                      \
-  if (!(cond))                                 \
-    __IssueError (__FILE__,                    \
-                 __LINE__,                    \
-                 __PRETTY_FUNCTION__, #cond, #exc, exc)
+ *  This is the main routine in the exception mechanism for debug mode
+ *  error checking. See the
+ *  #ExceptionBase# class for more information.
+ *
+ *  @memo Assert that a certain condition is fulfilled, otherwise
+ *   issue an error and abort the program.
+ *  @see ExceptionBase
+ *  @author Wolfgang Bangerth, November 1997, extensions 1998
+ */
+#define Assert(cond, exc)                              \
+  if (!(cond))                                         \
+    __IssueError_Assert (__FILE__,                    \
+                        __LINE__,                    \
+                        __PRETTY_FUNCTION__, #cond, #exc, exc)
 
 
 #else        ////////////////////////////////////////
@@ -270,100 +435,62 @@ void __IssueError (const char *file,
 
 
 /**
-    Declare an exception class without any additional parameters.
-    There is a whole family of #DeclException?# macros
-    where #?# is to be replaced by the number of additional
-    parameters (0 to 5 presently).
-    
-    The syntax is as follows:
-    \begin{verbatim}
-      DeclException2 (ExcDomain,
-                      int,
-                      int,
-                      << " i=" << arg1 << ", m=" << arg2);
-    \end{verbatim}
-    The first is the name of the exception class to be created.
-    The next arguments are the types of the parameters (in this
-    case there are two type names needed) and finally the output
-    sequence with which you can print additional information.
-    
-    The syntax of the output sequence is a bit weird but gets
-    clear once you see how this macro is defined:
-    \begin{verbatim}
-    class name : public ExceptionBase {
-      public:
-        name (const type1 a1, const type2 a2) :
-                       arg1 (a1), arg2(a2) {};
-        void PrintInfo (ostream &out) const {
-          out outsequence << endl;
-        };
-      private:
-        type1 arg1;
-        type2 arg2;
-    };
-    \end{verbatim}
-    The #PrintInfo# function is not declared #virtual# since we would
-    then create a class with virtual functions and only inlined code.
-    For this kind of class at least GNU C++ does not know where to put
-    the virtual method table and the program will not be compiled.
-    
-    If declared as specified, you can later use this exception class
-    in the following manner:
-    \begin{verbatim}
-      int i=5;
-      int m=3;
-      Assert (i<m, MyExc2(i,m));
-    \end{verbatim}
-    and the output if the condition fails will be
-    \begin{verbatim}
-      --------------------------------------------------------
-      An error occurred in line <301> of file <exc-test.cc>.
-      The violated condition was: 
-        i<m
-      The name and call sequence of the exception was:
-        MyExc2(i,m)
-      Additional Information: 
-        i=5, m=3
-      --------------------------------------------------------
-    \end{verbatim}
-    
-    Obviously for the #DeclException0(name)# macro, no types and
-    also no output sequence is allowed.
-    
-    @author Wolfgang Bangerth, November 1997
-    */
+ *  This is the main routine in the exception mechanism for run-time mode
+ *  error checking. See the
+ *  #ExceptionBase# class for more information.
+ *
+ *  @memo Assert that a certain condition is fulfilled, otherwise
+ *   throw an exception
+ *  @see ExceptionBase
+ *  @author Wolfgang Bangerth, November 1997, extensions 1998
+ */
+#define AssertThrow(cond, exc)                       \
+  if (!(cond))                                       \
+    __IssueError_Throw (__FILE__,                    \
+                       __LINE__,                    \
+                       __PRETTY_FUNCTION__, #cond, #exc, exc)
+
+  
+
+
+/**
+ * See the #ExceptionBase# class for a detailed description.
+ *
+ * @see ExceptionBase
+ * @author Wolfgang Bangerth, November 1997
+ */
 #define DeclException0(Exception0)  \
 class Exception0 :  public ExceptionBase {};
 
-                                /**
-                                 *  Declare an exception class with
-                                 *  one additional parameter.
-                                 *
-                                 *  @see DeclException0
-                                 */
+/**
+  *  Declare an exception class with
+  *  one additional parameter.
+  *
+  *  @see ExceptionBase
+  */
 #define DeclException1(Exception1, type1, outsequence)                \
 class Exception1 : public ExceptionBase {                             \
   public:                                                             \
       Exception1 (const type1 a1) : arg1 (a1) {};                     \
-      void PrintInfo (ostream &out) const {                           \
+      virtual void PrintInfo (ostream &out) const {                           \
         out outsequence << endl;                                      \
       };                                                              \
   private:                                                            \
       const type1 arg1;                                               \
 }
 
-                                /**
                                *  Declare an exception class with
                                *  two additional parameters.
                                *
-                                 *  @see DeclException0
                                */
+/**
+ *  Declare an exception class with
+ *  two additional parameters.
+ *
+ *  @see ExceptionBase
+ */
 #define DeclException2(Exception2, type1, type2, outsequence)         \
 class Exception2 : public ExceptionBase {                             \
   public:                                                             \
       Exception2 (const type1 a1, const type2 a2) :                   \
              arg1 (a1), arg2(a2) {};                                 \
-      void PrintInfo (ostream &out) const {                           \
+      virtual void PrintInfo (ostream &out) const {                           \
         out outsequence << endl;                                      \
       };                                                              \
   private:                                                            \
@@ -371,18 +498,18 @@ class Exception2 : public ExceptionBase {                             \
       const type2 arg2;                                               \
 }
 
-                                /**
                                *  Declare an exception class with
                                *  three additional parameters.
                                *
-                                 *  @see DeclException0
                                */
+/**
+ *  Declare an exception class with
+ *  three additional parameters.
+ *
+ *  @see ExceptionBase
+ */
 #define DeclException3(Exception3, type1, type2, type3, outsequence)  \
 class Exception3 : public ExceptionBase {                             \
   public:                                                             \
       Exception3 (const type1 a1, const type2 a2, const type3 a3) :   \
              arg1 (a1), arg2(a2), arg3(a3) {};                       \
-      void PrintInfo (ostream &out) const {                           \
+      virtual void PrintInfo (ostream &out) const {                           \
         out outsequence << endl;                                      \
       };                                                              \
   private:                                                            \
@@ -391,19 +518,19 @@ class Exception3 : public ExceptionBase {                             \
       const type3 arg3;                                               \
 }
 
-                                /**
                                *  Declare an exception class with
                                *  four additional parameters.
                                *
-                                 *  @see DeclException0
                                */
+/**
+ *  Declare an exception class with
+ *  four additional parameters.
+ *
+ *  @see ExceptionBase
+ */
 #define DeclException4(Exception4, type1, type2, type3, type4, outsequence) \
 class Exception4 : public ExceptionBase {                             \
   public:                                                             \
       Exception4 (const type1 a1, const type2 a2,                     \
            const type3 a3, const type4 a4) :                         \
              arg1 (a1), arg2(a2), arg3(a3), arg4(a4) {};             \
-      void PrintInfo (ostream &out) const {                           \
+      virtual void PrintInfo (ostream &out) const {                           \
         out outsequence << endl;                                      \
       };                                                              \
   private:                                                            \
@@ -413,19 +540,19 @@ class Exception4 : public ExceptionBase {                             \
       const type4 arg4;                                               \
 }
 
-                                /**
                                *  Declare an exception class with
                                *  five additional parameters.
                                *
-                                 *  @see DeclException0
                                */
+/**
+ *  Declare an exception class with
+ *  five additional parameters.
+ *
+ *  @see ExceptionBase
+ */
 #define DeclException5(Exception5, type1, type2, type3, type4, type5, outsequence) \
 class Exception5 : public 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) {};   \
-      void PrintInfo (ostream &out) const {                           \
+      virtual void PrintInfo (ostream &out) const {                           \
         out outsequence << endl;                                      \
       };                                                              \
   private:                                                            \
@@ -440,29 +567,6 @@ class Exception5 : public ExceptionBase {                             \
 
 
 
-
-/* ----------------------- Declare some global exceptions which are
-                           not generated by the Assert mechanism, but
-                          are rather used for the throw and catch
-                          way.
-*/
-
-
-/**
- * Exception class to be thrown whenever an I/O operation in the library
- * fails.
- */
-class GlobalExcIO : public exception
-{
-  public:
-    virtual const char * what () const {
-      return __PRETTY_FUNCTION__;
-    };
-};
-
-    
-
-
 /*----------------------------   exceptions.h     ---------------------------*/
 /* end of #ifndef __exceptions_H */
 #endif
index 9b1a8ba44ac4dded13b763a973f814159f80adf2..126414a5e481aaead233f8aff0e6bf2b2682e34a 100644 (file)
@@ -721,7 +721,10 @@ class ParameterHandler {
                                      * Exception
                                      */
     DeclException0 (ExcInternalError);
-
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
     
   private:
                                     /**
index 5a3d61fa46f8b403e84985e95a956e5caa4ec30e..1fd4fe49690d55a75386bb788c80e53a1608a891 100644 (file)
@@ -358,9 +358,6 @@ ostream & operator << (ostream &out, const Tensor<1,dim> &p) {
     out << p[i] << ' ';
   out << p[dim-1];
 
-  if (!out)
-    throw GlobalExcIO ();
-
   return out;
 };
 
@@ -370,9 +367,6 @@ inline
 ostream & operator << (ostream &out, const Tensor<1,1> &p) {
   out << p[0];
 
-  if (!out)
-    throw GlobalExcIO ();
-
   return out;
 };
   
index 2cafb3adcfc16c55d2486f39d9f8d9307a5dde09..186a07d7223bcdd1986ead9645c10ec47d84d7bf 100644 (file)
@@ -131,8 +131,7 @@ ParameterHandler::~ParameterHandler () {};
 
 
 bool ParameterHandler::read_input (istream &input) {
-  if (!input)
-    throw GlobalExcIO ();
+  AssertThrow (input, ExcIO());
 
   string line;
   int lineno=0;
@@ -361,9 +360,8 @@ ostream & ParameterHandler::print_parameters (ostream &out, OutputStyle style) {
                                   // given as "style"
   Assert ((style == Text) || (style == LaTeX), ExcNotImplemented());
 
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
   switch (style) 
     {
       case Text:
@@ -406,8 +404,7 @@ void ParameterHandler::print_parameters_section (ostream &out,
                                   // given as "style"
   Assert ((style == Text) || (style == LaTeX), ExcNotImplemented());
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 
   Section *pd = get_present_defaults_subsection ();
   Section *pc = get_present_changed_subsection ();
@@ -728,8 +725,7 @@ MultipleParameterLoop::~MultipleParameterLoop () {};
 
 
 bool MultipleParameterLoop::read_input (istream &input) {
-  if (!input)
-    throw GlobalExcIO ();
+  AssertThrow (input, ExcIO());
 
   bool x = ParameterHandler::read_input (input);
   if (x) init_branches ();
index 88daaf2bad0367d9de90083dbfb794a649a1d69a..4afb7c20f5707ca4f3766ba9eb54effe45b102f6 100644 (file)
@@ -289,6 +289,10 @@ class ConstraintMatrix {
                                      * Exception
                                      */
     DeclException0 (ExcWrongDimension);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
     
   private:
 
index b08baa758bd0c15d37b619c7b7a51ae4a29f97da..f51f9844ed689f9e007c1bddbf2238d94fba23ea 100644 (file)
@@ -2423,6 +2423,10 @@ class Triangulation : public TriaDimensionInfo<dim>, public Subscriptor {
                                      * Exception
                                      */
     DeclException0 (ExcInvalidParameterValue);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
                                     //@}
   protected:
 
index 22974a278cc4a116c6609a5abaaa47f91259cfe9..144def8426ab3a8feba927a8f54991650bf68559 100644 (file)
@@ -170,6 +170,10 @@ class DataIn {
                                      * Exception
                                      */
     DeclException0 (ExcInternalError);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
     
   private:
                                     /**
@@ -423,6 +427,37 @@ class DataOut {
                                      * object of this class.
                                      */
     static string default_suffix (const OutputFormat output_format);
+
+                                    /**
+                                     * Return the #OutputFormat# value
+                                     * corresponding to the given string. If
+                                     * the string does not match any known
+                                     * format, an exception is thrown.
+                                     *
+                                     * Since this function does not need data
+                                     * from this object, it is static and can
+                                     * thus be called without creating an
+                                     * object of this class. Its main purpose
+                                     * is to allow a program to use any
+                                     * implemented output format without the
+                                     * need to extend the program's parser
+                                     * each time a new format is implemented.
+                                     *
+                                     * To get a list of presently available
+                                     * format names, e.g. to give it to the
+                                     * #ParameterHandler# class, use the
+                                     * function #get_output_format_names ()#.
+                                     */
+    static OutputFormat parse_output_format (const string format_name);
+
+                                    /**
+                                     * Return a list of implemented output
+                                     * formats. The different names are
+                                     * separated by vertical bar signs (#`|'#)
+                                     * as used by the #ParameterHandler#
+                                     * classes.
+                                     */
+    static string get_output_format_names ();
     
                                     /**
                                      * Exception
@@ -452,6 +487,14 @@ class DataOut {
                    << "Please use only the characters [a-zA-Z0-9_<>()] for" << endl
                    << "description strings since AVS will only accept these." << endl
                    << "The string you gave was <" << arg1 << ">.");
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcInvalidState);
     
   private:
 
index 12aec083a4033462ae7b646eee3a2a9cb6d29408..c06c3f6c66eb8a89cb355ede553fc7be09f4ced5 100644 (file)
@@ -706,6 +706,5 @@ void ConstraintMatrix::print (ostream &out) const {
          << " " << lines[i].entries[j].first
          << ":  " << lines[i].entries[j].second << endl;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
index 0b336ebe532461b2ffeadcfff275cd51e94b057f..ce65300c09117b97adbbd24b20a25a6ebc68b619 100644 (file)
@@ -2225,16 +2225,14 @@ void Triangulation<dim>::print_gnuplot (ostream &out, const unsigned int level)
                               active_cell_iterator(end()) :
                               begin_active (level+1));
 
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
   out << "#Active cells on level " << level
       << ": " << n_active_cells (level) << endl;
   for (; cell != endc; ++cell)
     print_gnuplot (out, cell);
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 
@@ -2244,15 +2242,13 @@ void Triangulation<dim>::print_gnuplot (ostream &out, const unsigned int level)
 template <>
 void Triangulation<1>::print_gnuplot (ostream &out,
                                      const active_cell_iterator & cell) const {
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
   out << cell->vertex(0) << " " << cell->level() << endl
       << cell->vertex(1) << " " << cell->level() << endl
       << endl;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 #endif
@@ -2263,9 +2259,8 @@ void Triangulation<1>::print_gnuplot (ostream &out,
 template <>
 void Triangulation<2>::print_gnuplot (ostream &out,
                                      const active_cell_iterator & cell) const {
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
   out << cell->vertex(0) << " " << cell->level() << endl
       << cell->vertex(1) << " " << cell->level() << endl
       << cell->vertex(2) << " " << cell->level() << endl
@@ -2274,8 +2269,7 @@ void Triangulation<2>::print_gnuplot (ostream &out,
       << endl  // double new line for gnuplot 3d plots
       << endl;
 
-  if (!out)
-    throw GlobalExcIO ();  
+  AssertThrow (out, ExcIO());
 };
 
 #endif
@@ -3861,9 +3855,8 @@ void Triangulation<dim>::write_bool_vector (const unsigned int  magic_number1,
   for (unsigned int position=0; position<N; ++position)
     flags[position/8] |= (v[position] ? (1<<(position%8)) : 0);
 
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
                                   // format:
                                   // 0. magic number
                                   // 1. number of flags
@@ -3877,8 +3870,7 @@ void Triangulation<dim>::write_bool_vector (const unsigned int  magic_number1,
   
   delete[] flags;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 
@@ -3888,8 +3880,7 @@ void Triangulation<dim>::read_bool_vector (const unsigned int  magic_number1,
                                           vector<bool>       &v,
                                           const unsigned int  magic_number2,
                                           istream            &in) {
-  if (!in)
-    throw GlobalExcIO ();
+  AssertThrow (in, ExcIO());
 
   unsigned int magic_number;
   in >> magic_number;
@@ -3915,8 +3906,7 @@ void Triangulation<dim>::read_bool_vector (const unsigned int  magic_number1,
 
   delete[] flags;
 
-  if (!in)
-    throw GlobalExcIO ();
+  AssertThrow (in, ExcIO());
 };
 
 
index 0c2a00e2b59d6e97c39e918b998ba9ffa568d6f0..9ab3f2b8fcf968db1885fa0677ef13e5bb88662f 100644 (file)
@@ -42,9 +42,8 @@ void DataIn<dim>::read_ucd (istream &in) {
   Assert (tria != 0, ExcNoTriangulationSelected());
   Assert ((1<=dim) && (dim<=2), ExcNotImplemented());
 
-  if (!in)
-    throw GlobalExcIO ();
-
+  AssertThrow (in, ExcIO());
+  
                                   // skip comments at start of file
   char c;
   while (in.get(c), c=='#') 
@@ -164,8 +163,7 @@ void DataIn<dim>::read_ucd (istream &in) {
                                   // check that no forbidden arrays are used
   Assert (subcelldata.check_consistency(dim), ExcInternalError());
 
-  if (!in)
-    throw GlobalExcIO ();
+  AssertThrow (in, ExcIO());
 
   tria->create_triangulation (vertices, cells, subcelldata);
 };
@@ -388,9 +386,9 @@ void DataOut<dim>::write_ucd (ostream &out) const {
     };
                                   // no cell data
                                   // no model data
-  if (!out)
-    throw GlobalExcIO ();
 
+                                  // assert the stream is still ok
+  AssertThrow (out, ExcIO());
 };
 
 
@@ -461,8 +459,7 @@ void DataOut<dim>::write_ucd_faces (ostream &out,
        ++index;
       };         
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
       
@@ -589,9 +586,8 @@ void DataOut<dim>::write_gnuplot (ostream &out, unsigned int accuracy) const
     out << endl;
     }
   delete [] values;
-  
-  if (!out)
-    throw GlobalExcIO ();
+
+  AssertThrow (out, ExcIO());
 }
 
 
@@ -701,8 +697,7 @@ void DataOut<dim>::write_gnuplot_draft (ostream &out) const
        };
     };
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 
@@ -797,8 +792,7 @@ void DataOut<2>::write_povray (ostream &out) const {
     };
   out << "}";     
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
       
@@ -846,6 +840,32 @@ string DataOut<dim>::default_suffix (const OutputFormat output_format) {
   
 
 
+template <int dim>
+DataOut<dim>::OutputFormat
+DataOut<dim>::parse_output_format (const string format_name) {
+  if (format_name == "ucd")
+    return ucd;
+
+  if (format_name == "gnuplot")
+    return gnuplot;
+
+  if (format_name == "gnuplot draft")
+    return gnuplot_draft;
+
+  if (format_name == "povray")
+    return povray;
+
+  AssertThrow (false, ExcInvalidState ());
+};
+
+
+
+template <int dim>
+string DataOut<dim>::get_output_format_names () {
+  return "ucd|gnuplot|gnuplot draft|povray";
+};
+
+
 
 //explicite instantiations
 
index a133e3037212d711fe56e24d99ee28fcf1ac9ec0..34e85950a1ade31e3387adcc1b5ea6dea7a66889 100644 (file)
@@ -479,6 +479,10 @@ class dFMatrix
                    int,
                    << "This function is not implemented for the given"
                    << " matrix dimension " << arg1);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
 };
 
 
index 4de7d590d6f2c978e7411989df81965239f032d9..4a8f5f3019589bccd019940190df847c2bc6781a 100644 (file)
@@ -317,6 +317,10 @@ class dSMatrixStruct
                                      * Exception
                                      */
     DeclException0 (ExcInternalError);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
 
   private:
     unsigned int max_dim;
@@ -693,7 +697,11 @@ class dSMatrix
                                      * Exception
                                      */
     DeclException0 (ExcDifferentSparsityPatterns);
-
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
+    
   private:
     const dSMatrixStruct * cols;
     double* val;
index 2ed3a1452a1472a733edacf55cdef5e6d3314c96..39f61eaf6e911348d7919d1c0bfe4aca9adcef2a 100644 (file)
@@ -410,6 +410,10 @@ class dVector {
                                      * Exception
                                      */
     DeclException0 (ExcEmptyVector);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
 };
 
 
index 8dfd49e033d75affc6ec6d17b9f0b9629b430e5b..fb00b874411615f8f9deccd48dfe205ea32a59a5 100644 (file)
@@ -1111,8 +1111,7 @@ void dFMatrix::print_formatted (ostream &out, const unsigned int precision) cons
       out << endl;
     };
 
-  if (!out)
-    throw GlobalExcIO ();
-
+  AssertThrow (out, ExcIO());
+  
   out.setf (0, ios::floatfield);                 // reset output format
 };
index 89203aa23847eafd57b4c901195382d2af80528d..cc1925ef70b9c9af3be9566e62bc4bdd88c8e7ed 100644 (file)
@@ -332,8 +332,7 @@ dSMatrixStruct::print_gnuplot (ostream &out) const
       if (colnums[j]>=0)
        out << i << " " << -colnums[j] << endl;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 }
 
 
@@ -756,8 +755,7 @@ void dSMatrix::print (ostream &out) const {
     for (unsigned int j=cols->rowstart[i]; j<cols->rowstart[i+1]; ++j)
       out << "(" << i << "," << cols->colnums[j] << ") " << val[j] << endl;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 
@@ -778,8 +776,7 @@ void dSMatrix::print_formatted (ostream &out, const unsigned int precision) cons
          out << setw(precision+8) << " ";
       out << endl;
     };
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 
   out.setf (0, ios::floatfield);                 // reset output format
 };
index 6001a6b4a10d3284492f2e2321bf1ca6a9b23bc7..c033fe6fd76416b45e37e9bcab97cf60d1ffefc2 100644 (file)
@@ -512,8 +512,7 @@ void dVector::print (ostream &out) const {
   for (unsigned int i=0; i<size(); ++i)
     out << val[i] << endl;
 
-  if (!out)
-    throw GlobalExcIO ();
+  AssertThrow (out, ExcIO());
 };
 
 

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.