src/work/klao/error.h
author klao
Fri, 07 Jan 2005 00:43:54 +0000
changeset 1056 cbc27743e17a
parent 993 src/lemon/error.h@21d1b4fa1b24
child 1061 e3433c024123
permissions -rw-r--r--
Exception hierarchy sketch.
Exception safe exception classes.
     1 /* -*- C++ -*-
     2  * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_ERROR_H
    18 #define LEMON_ERROR_H
    19 
    20 //! \ingroup misc
    21 //! \file
    22 //! \brief Basic error handling (signaling) routines.
    23 
    24 #include <exception>
    25 #include <string>
    26 #include <sstream>
    27 
    28 #include <boost/shared_ptr.hpp>
    29 
    30 namespace lemon {
    31 
    32   /// Exception-safe convenient "error message" class.
    33   class ErrorMessage {
    34   protected:
    35     boost::shared_ptr<std::ostringstream> buf;
    36     
    37     bool init() throw() {
    38       try {
    39 	buf.reset(new std::ostringstream);
    40       }
    41       catch(...) {
    42 	buf.reset();
    43       }
    44       return buf;
    45     }
    46 
    47   public:
    48 
    49     ErrorMessage() throw() { init(); }
    50 
    51     ErrorMessage(const char *message) throw() {
    52       init();
    53       *this << message;
    54     }
    55 
    56     ErrorMessage(const std::string &message) throw() {
    57       init();
    58       *this << message;
    59     }
    60 
    61     template <typename T>
    62     ErrorMessage& operator<<(const T &t) throw() {
    63       if( !buf ) return *this;
    64 
    65       try {
    66 	*buf << t;
    67       }
    68       catch(...) {
    69 	buf.reset();
    70       }
    71     }
    72 
    73     const char* message() throw() {
    74       if( !buf ) return 0;
    75 
    76       const char* mes = 0;
    77       try {
    78 	mes = buf->str().c_str();
    79       }
    80       catch(...) {}
    81       return mes;
    82     }
    83     
    84   };
    85 
    86   /**
    87    * \brief Generic exception class.
    88    *
    89    * Base class for exceptions used in LEMON.
    90    */
    91   class Exception : public std::exception, public ErrorMessage {
    92   public:
    93     Exception() throw() {}
    94     explicit Exception(const std::string &s) throw()
    95       : ErrorMessage(s) {}
    96     virtual ~Exception() throw() {}
    97     
    98     virtual const char* what() const throw() {
    99       const char *mes = message();
   100       if( mes ) return mes;
   101       return "lemon::Exception";
   102     }
   103   };
   104 
   105 
   106   class LogicError : public Exception {
   107     explicit LogicError(const std::string &s)
   108       : Exception(s) {}
   109   };
   110 
   111   class RuntimeError : public Exception {
   112     explicit RuntimeError(const std::string &s)
   113       : Exception(s) {}
   114   };
   115 
   116   class RangeError : public RuntimeError {
   117     explicit RangeError(const std::string &s)
   118       : RuntimeError(s) {}
   119   };
   120 
   121   class IOError : public RuntimeError {
   122     explicit IOError(const std::string &s)
   123       : RuntimeError(s) {}
   124   };
   125 
   126   class DataFormatError : public IOError {
   127     explicit DataFormatError(const std::string &message)
   128       : IOError(message) : line(0) {}
   129     DataFormatError(const std::string &file_name, int line_num,
   130 		    sconst std::string &message)
   131       : IOError(message), line(line_num) { set_file(file_name); }
   132 
   133     void set_line(int line_num) { line=line_num; }
   134     void set_file(const std::string &file_name) {
   135       try {
   136 	file.reset(new std::string);
   137 	*file = file_name;
   138       }
   139       catch(...) {
   140 	file.reset();
   141       }
   142     }
   143 
   144     virtual const char* what() const {
   145       const char *mes = 0;
   146       try {
   147 	std::ostringstream ostr;
   148 	ostr << IOError::what();
   149 	if( file || line ) {
   150 	  ostr << " (";
   151 	  if( file ) ostr << "in file" << *file;
   152 	  if( line ) ostr << " at line" << line;
   153 	}
   154 	mes = ostr.str().c_str();
   155       }
   156       catch(...) {}
   157       if( mes ) return mes;
   158       return "lemon::DataFormatError";
   159     }
   160   };
   161 
   162 
   163 
   164   /****************  Macros  ****************/
   165 
   166 
   167   /**
   168    * \brief Macro for assertions with customizable message
   169    */
   170 
   171 # define lemon_assert(exp, msg) \
   172     if(!(exp)) { \
   173       std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
   174       abort; \
   175     }
   176 
   177 
   178   /**
   179    * \brief Macro for mark not yet implemented features.
   180    *
   181    * \todo Is this the right place for this? It should be used only in
   182    * modules under development.
   183    */
   184 
   185 # define FIXME(msg) lemon_assert(0, "FIXME: " msg)
   186 
   187 }
   188 #endif // LEMON_ERROR_H