| 1 | //
 | 
|---|
| 2 | // scexception.h
 | 
|---|
| 3 | //
 | 
|---|
| 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
| 5 | //
 | 
|---|
| 6 | // Author: Joseph Kenny <jpkenny@sandia.gov>
 | 
|---|
| 7 | // Maintainer: LPS
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // This file is part of the SC Toolkit.
 | 
|---|
| 10 | //
 | 
|---|
| 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
| 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
| 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
| 14 | // any later version.
 | 
|---|
| 15 | //
 | 
|---|
| 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
| 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 19 | // GNU Library General Public License for more details.
 | 
|---|
| 20 | //
 | 
|---|
| 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
| 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
| 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
| 24 | //
 | 
|---|
| 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
| 26 | //
 | 
|---|
| 27 | 
 | 
|---|
| 28 | #ifdef __GNUC__
 | 
|---|
| 29 | #pragma interface
 | 
|---|
| 30 | #endif
 | 
|---|
| 31 | 
 | 
|---|
| 32 | #ifndef _util_misc_scexception_h
 | 
|---|
| 33 | #define _util_misc_scexception_h
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #ifndef _util_class_class_h
 | 
|---|
| 36 | #include <util/class/class.h>
 | 
|---|
| 37 | #endif
 | 
|---|
| 38 | 
 | 
|---|
| 39 | #include <stddef.h>
 | 
|---|
| 40 | #include <exception>
 | 
|---|
| 41 | #include <sstream>
 | 
|---|
| 42 | #include <vector>
 | 
|---|
| 43 | 
 | 
|---|
| 44 | namespace sc {
 | 
|---|
| 45 | 
 | 
|---|
| 46 | /** This is a std::exception specialization that records information
 | 
|---|
| 47 |     about where an exception took place.
 | 
|---|
| 48 |  */
 | 
|---|
| 49 | class SCException: public std::exception {
 | 
|---|
| 50 |     const char *description_;
 | 
|---|
| 51 |     const char *file_;
 | 
|---|
| 52 |     int line_;
 | 
|---|
| 53 |     const ClassDesc* class_desc_;
 | 
|---|
| 54 |     const char *exception_type_;
 | 
|---|
| 55 |     std::ostringstream *elaboration_;
 | 
|---|
| 56 | 
 | 
|---|
| 57 |   public:
 | 
|---|
| 58 |     SCException(const char *description = 0,
 | 
|---|
| 59 |                 const char *file = 0,
 | 
|---|
| 60 |                 int line = 0,
 | 
|---|
| 61 |                 const ClassDesc *class_desc = 0,
 | 
|---|
| 62 |                 const char *exception_type = "SCException") throw();
 | 
|---|
| 63 |     SCException(const SCException&) throw();
 | 
|---|
| 64 |     ~SCException() throw();
 | 
|---|
| 65 | 
 | 
|---|
| 66 |     /** Reimplementation of std::exception::what().  The returned
 | 
|---|
| 67 |         std::string is only valid for the lifetime of this object. */
 | 
|---|
| 68 |     const char* what() const throw();
 | 
|---|
| 69 | 
 | 
|---|
| 70 |     const char *description() const throw() { return description_; }
 | 
|---|
| 71 |     const char *file() const throw() { return file_; }
 | 
|---|
| 72 |     int line() const throw() { return line_; }
 | 
|---|
| 73 |     const ClassDesc *class_desc() const throw() { return class_desc_; }
 | 
|---|
| 74 |     const char *exception_type() const throw() { return exception_type_; }
 | 
|---|
| 75 | 
 | 
|---|
| 76 |     /** Returns a stream where addition information about the exception can
 | 
|---|
| 77 |         be written.  This will throw if a valid stream cannot be returned
 | 
|---|
| 78 |         (possibly due to low memory). */
 | 
|---|
| 79 |     std::ostream &elaborate();
 | 
|---|
| 80 | };
 | 
|---|
| 81 | 
 | 
|---|
| 82 | // ///////////////////////////////////////////////////////////////////////
 | 
|---|
| 83 | // Programming Error Exceptions
 | 
|---|
| 84 | 
 | 
|---|
| 85 | /** This is thrown when a situations arises that should be impossible.
 | 
|---|
| 86 |  */
 | 
|---|
| 87 | class ProgrammingError: public SCException {
 | 
|---|
| 88 | 
 | 
|---|
| 89 |   public:
 | 
|---|
| 90 |     ProgrammingError(const char *description = 0,
 | 
|---|
| 91 |                      const char *file = 0,
 | 
|---|
| 92 |                      int line = 0,
 | 
|---|
| 93 |                      const ClassDesc *class_desc = 0,
 | 
|---|
| 94 |                      const char *exception_type = "ProgrammingError") throw();
 | 
|---|
| 95 |     ProgrammingError(const ProgrammingError&) throw();
 | 
|---|
| 96 |     ~ProgrammingError() throw();
 | 
|---|
| 97 | };
 | 
|---|
| 98 | 
 | 
|---|
| 99 | /** This is thrown when an attempt is made to use a feature that
 | 
|---|
| 100 |     is not yet implemented.
 | 
|---|
| 101 |  */
 | 
|---|
| 102 | class FeatureNotImplemented: public ProgrammingError {
 | 
|---|
| 103 | 
 | 
|---|
| 104 |   public:
 | 
|---|
| 105 |     FeatureNotImplemented(const char *description = 0,
 | 
|---|
| 106 |                           const char *file = 0,
 | 
|---|
| 107 |                           int line = 0,
 | 
|---|
| 108 |                           const ClassDesc *class_desc = 0,
 | 
|---|
| 109 |                           const char *exception_type = "FeatureNotImplemented")
 | 
|---|
| 110 |         throw();
 | 
|---|
| 111 |     FeatureNotImplemented(const FeatureNotImplemented&) throw();
 | 
|---|
| 112 |     ~FeatureNotImplemented() throw();
 | 
|---|
| 113 | };
 | 
|---|
| 114 | 
 | 
|---|
| 115 | // ///////////////////////////////////////////////////////////////////////
 | 
|---|
| 116 | // Input Error Exceptions
 | 
|---|
| 117 | 
 | 
|---|
| 118 | /** This is thrown when invalid input is provided.  Note that sometimes
 | 
|---|
| 119 |     input can be internally generated, so what logically would be a
 | 
|---|
| 120 |     ProgrammingError could result in an InputError being thrown.
 | 
|---|
| 121 |  */
 | 
|---|
| 122 | class InputError: public SCException {
 | 
|---|
| 123 |     const char *keyword_;
 | 
|---|
| 124 |     char *value_;
 | 
|---|
| 125 | 
 | 
|---|
| 126 |   public:
 | 
|---|
| 127 |     InputError(const char *description = 0,
 | 
|---|
| 128 |                const char *file = 0,
 | 
|---|
| 129 |                int line = 0,
 | 
|---|
| 130 |                const char *keyword = 0,
 | 
|---|
| 131 |                const char *value = 0,
 | 
|---|
| 132 |                const ClassDesc *class_desc = 0,
 | 
|---|
| 133 |                const char *exception_type = "InputError") throw();
 | 
|---|
| 134 |     InputError(const InputError&) throw();
 | 
|---|
| 135 |     ~InputError() throw();
 | 
|---|
| 136 |     const char *keyword() const throw() { return keyword_; }
 | 
|---|
| 137 |     const char *value() const throw() { return value_; }
 | 
|---|
| 138 | };
 | 
|---|
| 139 | 
 | 
|---|
| 140 | // ///////////////////////////////////////////////////////////////////////
 | 
|---|
| 141 | // System Exceptions
 | 
|---|
| 142 | 
 | 
|---|
| 143 | /** This is thrown when a system problem occurs.
 | 
|---|
| 144 |  */
 | 
|---|
| 145 | class SystemException: public SCException {
 | 
|---|
| 146 | 
 | 
|---|
| 147 |   public:
 | 
|---|
| 148 |     SystemException(const char *description = 0,
 | 
|---|
| 149 |                     const char *file = 0,
 | 
|---|
| 150 |                     int line = 0,
 | 
|---|
| 151 |                     const ClassDesc *class_desc = 0,
 | 
|---|
| 152 |                     const char *exception_type = "SystemException") throw();
 | 
|---|
| 153 |     SystemException(const SystemException&) throw();
 | 
|---|
| 154 |     ~SystemException() throw();
 | 
|---|
| 155 | };
 | 
|---|
| 156 | 
 | 
|---|
| 157 | /** This is thrown when a memory allocation fails.
 | 
|---|
| 158 |  */
 | 
|---|
| 159 | class MemAllocFailed: public SystemException {
 | 
|---|
| 160 |     size_t nbyte_;
 | 
|---|
| 161 | 
 | 
|---|
| 162 |   public:
 | 
|---|
| 163 |     MemAllocFailed(const char *description = 0,
 | 
|---|
| 164 |                    const char *file = 0,
 | 
|---|
| 165 |                    int line = 0,
 | 
|---|
| 166 |                    size_t nbyte = 0,
 | 
|---|
| 167 |                    const ClassDesc *class_desc = 0,
 | 
|---|
| 168 |                    const char *exception_type = "MemAllocFailed") throw();
 | 
|---|
| 169 |     MemAllocFailed(const MemAllocFailed&) throw();
 | 
|---|
| 170 |     ~MemAllocFailed() throw();
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     /// Returns the number of bytes used in the failed allocation attempt.
 | 
|---|
| 173 |     size_t nbyte() const throw() { return nbyte_; }
 | 
|---|
| 174 | };
 | 
|---|
| 175 | 
 | 
|---|
| 176 | /** This is thrown when an operation on a file fails.
 | 
|---|
| 177 |  */
 | 
|---|
| 178 | class FileOperationFailed: public SystemException {
 | 
|---|
| 179 |   public:
 | 
|---|
| 180 |     enum FileOperation { Unknown, OpenR, OpenW, OpenRW,
 | 
|---|
| 181 |                          Close, Read, Write, Corrupt, Other };
 | 
|---|
| 182 | 
 | 
|---|
| 183 |   private:
 | 
|---|
| 184 |     const char *filename_;
 | 
|---|
| 185 |     FileOperation operation_;
 | 
|---|
| 186 | 
 | 
|---|
| 187 |   public:
 | 
|---|
| 188 |     FileOperationFailed(const char *description = 0,
 | 
|---|
| 189 |                    const char *source_file = 0,
 | 
|---|
| 190 |                    int line = 0,
 | 
|---|
| 191 |                    const char *filename = 0,
 | 
|---|
| 192 |                    FileOperation operation = Unknown,
 | 
|---|
| 193 |                    const ClassDesc *class_desc = 0,
 | 
|---|
| 194 |                    const char *exception_type = "FileOperationFailed") throw();
 | 
|---|
| 195 |     FileOperationFailed(const FileOperationFailed&) throw();
 | 
|---|
| 196 |     ~FileOperationFailed() throw();
 | 
|---|
| 197 | 
 | 
|---|
| 198 |     /** Returns the file name of the file that caused the error, if known.
 | 
|---|
| 199 |         Otherwise 0 is returned. */
 | 
|---|
| 200 |     const char * filename() const throw() { return filename_; }
 | 
|---|
| 201 |     FileOperation operation() const throw() { return operation_; }
 | 
|---|
| 202 | };
 | 
|---|
| 203 | 
 | 
|---|
| 204 | /** This is thrown when an system call fails with an errno.
 | 
|---|
| 205 |  */
 | 
|---|
| 206 | class SyscallFailed: public SystemException {
 | 
|---|
| 207 |     const char *syscall_;
 | 
|---|
| 208 |     int err_;
 | 
|---|
| 209 | 
 | 
|---|
| 210 |   public:
 | 
|---|
| 211 |     SyscallFailed(const char *description = 0,
 | 
|---|
| 212 |                   const char *source_file = 0,
 | 
|---|
| 213 |                   int line = 0,
 | 
|---|
| 214 |                   const char *syscall = 0,
 | 
|---|
| 215 |                   int err = 0, 
 | 
|---|
| 216 |                   const ClassDesc *class_desc = 0,
 | 
|---|
| 217 |                   const char *exception_type = "SyscallFailed") throw();
 | 
|---|
| 218 |     SyscallFailed(const SyscallFailed&) throw();
 | 
|---|
| 219 |     ~SyscallFailed() throw();
 | 
|---|
| 220 | 
 | 
|---|
| 221 |     /** Returns the file name of the file that caused the error, if known.
 | 
|---|
| 222 |         Otherwise 0 is returned. */
 | 
|---|
| 223 |     const char * syscall() const throw() { return syscall_; }
 | 
|---|
| 224 |     int err() const throw() { return err_; }
 | 
|---|
| 225 | };
 | 
|---|
| 226 | 
 | 
|---|
| 227 | // ///////////////////////////////////////////////////////////////////////
 | 
|---|
| 228 | // Algorithm Exceptions
 | 
|---|
| 229 | 
 | 
|---|
| 230 | /** This exception is thrown whenever a problem with an algorithm is
 | 
|---|
| 231 |     encountered.
 | 
|---|
| 232 | */
 | 
|---|
| 233 | class AlgorithmException: public SCException {
 | 
|---|
| 234 | 
 | 
|---|
| 235 |   public:
 | 
|---|
| 236 |     AlgorithmException(const char *description = 0,
 | 
|---|
| 237 |                        const char *file = 0,
 | 
|---|
| 238 |                        int line = 0,
 | 
|---|
| 239 |                        const ClassDesc *class_desc = 0,
 | 
|---|
| 240 |                        const char *exception_type = "AlgorithmException")
 | 
|---|
| 241 |         throw();
 | 
|---|
| 242 |     AlgorithmException(const AlgorithmException&) throw();
 | 
|---|
| 243 |     ~AlgorithmException() throw();
 | 
|---|
| 244 | };
 | 
|---|
| 245 | 
 | 
|---|
| 246 | /** This is thrown when an iterative algorithm attempts to use more
 | 
|---|
| 247 |     iterations than allowed.
 | 
|---|
| 248 |  */
 | 
|---|
| 249 | class MaxIterExceeded: public AlgorithmException {
 | 
|---|
| 250 |     int max_iter_;
 | 
|---|
| 251 | 
 | 
|---|
| 252 |   public:
 | 
|---|
| 253 |     MaxIterExceeded(const char *description = 0,
 | 
|---|
| 254 |                     const char *file = 0,
 | 
|---|
| 255 |                     int line = 0,
 | 
|---|
| 256 |                     int maxiter = 0,
 | 
|---|
| 257 |                     const ClassDesc *class_desc = 0,
 | 
|---|
| 258 |                     const char *exception_type = "MaxIterExceeded") throw();
 | 
|---|
| 259 |     MaxIterExceeded(const MaxIterExceeded&) throw();
 | 
|---|
| 260 |     ~MaxIterExceeded() throw();
 | 
|---|
| 261 | 
 | 
|---|
| 262 |     int max_iter() const throw() { return max_iter_; }
 | 
|---|
| 263 | };
 | 
|---|
| 264 | 
 | 
|---|
| 265 | /** This is thrown when when some tolerance is exceeded.
 | 
|---|
| 266 |  */
 | 
|---|
| 267 | class ToleranceExceeded: public AlgorithmException {
 | 
|---|
| 268 |     double tolerance_;
 | 
|---|
| 269 |     double value_;
 | 
|---|
| 270 | 
 | 
|---|
| 271 | public:
 | 
|---|
| 272 |     ToleranceExceeded(const char *description = 0,
 | 
|---|
| 273 |                       const char *file = 0,
 | 
|---|
| 274 |                       int line = 0,
 | 
|---|
| 275 |                       double tol=0,
 | 
|---|
| 276 |                       double val=0,
 | 
|---|
| 277 |                       const ClassDesc *class_desc = 0,
 | 
|---|
| 278 |                       const char *exception_type = "ToleranceExceeded") throw();
 | 
|---|
| 279 |     ToleranceExceeded(const ToleranceExceeded&) throw();
 | 
|---|
| 280 |     ~ToleranceExceeded() throw();
 | 
|---|
| 281 |     double tolerance() throw() { return tolerance_; }
 | 
|---|
| 282 |     double value() throw() { return value_; }
 | 
|---|
| 283 | };
 | 
|---|
| 284 | 
 | 
|---|
| 285 | // ///////////////////////////////////////////////////////////////////////
 | 
|---|
| 286 | // Limit Exceeded Exceptions
 | 
|---|
| 287 | 
 | 
|---|
| 288 | /** This is thrown when a limit is exceeded.  It is more general than
 | 
|---|
| 289 |     ToleranceExceeded.  For problems that are numerical in nature and use
 | 
|---|
| 290 |     double types, then ToleranceExceeded should be used instead.
 | 
|---|
| 291 | */
 | 
|---|
| 292 | template <class T>
 | 
|---|
| 293 | class LimitExceeded: public SCException {
 | 
|---|
| 294 |     T limit_;
 | 
|---|
| 295 |     T value_;
 | 
|---|
| 296 | 
 | 
|---|
| 297 | public:
 | 
|---|
| 298 |     LimitExceeded(const char *description,
 | 
|---|
| 299 |                   const char *file,
 | 
|---|
| 300 |                   int line,
 | 
|---|
| 301 |                   T lim,
 | 
|---|
| 302 |                   T val,
 | 
|---|
| 303 |                   const ClassDesc *class_desc = 0,
 | 
|---|
| 304 |                   const char *exception_type = "LimitExceeded") throw():
 | 
|---|
| 305 |       SCException(description, file, line, class_desc, exception_type),
 | 
|---|
| 306 |       limit_(lim), value_(val)
 | 
|---|
| 307 |         {
 | 
|---|
| 308 |           try {
 | 
|---|
| 309 |               elaborate() << "value:       " << value_
 | 
|---|
| 310 |                           << std::endl
 | 
|---|
| 311 |                           << "limit:       " << limit_
 | 
|---|
| 312 |                           << std::endl;
 | 
|---|
| 313 |             }
 | 
|---|
| 314 |           catch(...) {
 | 
|---|
| 315 |             }
 | 
|---|
| 316 |         }
 | 
|---|
| 317 |     LimitExceeded(const LimitExceeded&ref) throw():
 | 
|---|
| 318 |       SCException(ref),
 | 
|---|
| 319 |       limit_(ref.limit_), value_(ref.value_)
 | 
|---|
| 320 |         {
 | 
|---|
| 321 |         }
 | 
|---|
| 322 |     ~LimitExceeded() throw() {}
 | 
|---|
| 323 |     T tolerance() throw() { return limit_; }
 | 
|---|
| 324 |     T value() throw() { return value_; }
 | 
|---|
| 325 | };
 | 
|---|
| 326 | 
 | 
|---|
| 327 | }
 | 
|---|
| 328 | 
 | 
|---|
| 329 | #endif
 | 
|---|
| 330 | 
 | 
|---|