Here is the class structure for exceptions:
Exception Logic_error ProgramException miscellaneous matrix error IndexException index out of bounds VectorException unable to convert matrix to vector NotSquareException matrix is not square (invert, solve) SubMatrixDimensionException out of bounds index of submatrix IncompatibleDimensionsException (multiply, add etc) NotDefinedException operation not defined (eg <) CannotBuildException copying a matrix where copy is undefined InternalException probably an error in newmat Runtime_error NPDException matrix not positive definite (Cholesky) ConvergenceException no convergence (e-values, non-linear, sort) SingularException matrix is singular (invert, solve) SolutionException no convergence in solution routine OverflowException floating point overflow Bad_alloc out of space (new fails)
I have attempted to mimic the exception class structure in the C++ standard library, by defining the Logic_error and Runtime_error classes.
If there is no catch statement or exceptions are disabled then my Terminate() function in myexcept.h is called. This prints out an error message, the dimensions and types of the matrices involved, the name of the routine detecting the exception, and any other information set by the Tracer class. Also see the section on error messages for additional notes on the messages generated by the exceptions.
You can also print this information by printing Exception::what().
See the file test_exc.cpp as an example of catching an exception and printing the error message.
The 08 version of newmat defined a member function void SetAction(int) to help customise the action when an exception is called. This has been deleted in the 09 version. Now include an instruction such as cout << Exception::what() << endl; in the Catch or CatchAll block to determine the action.
The library includes the alternatives of using the inbuilt exceptions provided by a compiler, simulating exceptions, or disabling exceptions. See customising for selecting the correct exception option.
The rest of this section describes my partial simulation of exceptions for compilers which do not support C++ exceptions. I use Carlos Vidal's article in the September 1992 C Users Journal as a starting point.
Newmat does a partial clean up of memory following throwing an exception - see the next section. However, the present version will leave a little heap memory unrecovered under some circumstances. I would not expect this to be a major problem, but it is something that needs to be sorted out.
The functions/macros I define are Try, Throw, Catch, CatchAll and CatchAndThrow. Try, Throw, Catch and CatchAll correspond to try, throw, catch and catch(...) in the C++ standard. A list of Catch clauses must be terminated by either CatchAll or CatchAndThrow but not both. Throw takes an Exception as an argument or takes no argument (for passing on an exception). I do not have a version of Throw for specifying which exceptions a function might throw. Catch takes an exception class name as an argument; CatchAll and CatchAndThrow don't have any arguments. Try, Catch and CatchAll must be followed by blocks enclosed in curly brackets.
I have added another macro ReThrow to mean a rethrow, Throw(). This was necessary to enable the package to be compatible with both my exception package and C++ exceptions.
If you want to throw an exception, use a statement like
Throw(Exception("Error message\n"));It is important to have the exception declaration in the Throw statement, rather than as a separate statement.
All exception classes must be derived from the class, Exception, defined in newmat and can contain only static variables. See the examples in newmat if you want to define additional exceptions.