src/work/klao/error.h
author klao
Sun, 09 Jan 2005 20:10:58 +0000
changeset 1065 340fe3cbb145
parent 1056 cbc27743e17a
child 1067 47939f501c81
permissions -rw-r--r--
update to doxygen v1.4.0
     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   ///\e 
    36     boost::shared_ptr<std::ostringstream> buf;
    37     
    38   ///\e 
    39     bool init() throw() {
    40       try {
    41 	buf.reset(new std::ostringstream);
    42       }
    43       catch(...) {
    44 	buf.reset();
    45       }
    46       return buf;
    47     }
    48 
    49   public:
    50 
    51   ///\e 
    52     ErrorMessage() throw() { init(); }
    53 
    54   ///\e 
    55     ErrorMessage(const char *message) throw() {
    56       init();
    57       *this << message;
    58     }
    59 
    60   ///\e 
    61     ErrorMessage(const std::string &message) throw() {
    62       init();
    63       *this << message;
    64     }
    65 
    66   ///\e 
    67     template <typename T>
    68     ErrorMessage& operator<<(const T &t) throw() {
    69       if( !buf ) return *this;
    70 
    71       try {
    72 	*buf << t;
    73       }
    74       catch(...) {
    75 	buf.reset();
    76       }
    77     }
    78 
    79   ///\e 
    80     const char* message() throw() {
    81       if( !buf ) return 0;
    82 
    83       const char* mes = 0;
    84       try {
    85 	mes = buf->str().c_str();
    86       }
    87       catch(...) {}
    88       return mes;
    89     }
    90     
    91   };
    92 
    93   /**
    94    * \brief Generic exception class.
    95    *
    96    * Base class for exceptions used in LEMON.
    97    */
    98   class Exception : public std::exception, public ErrorMessage {
    99   public:
   100   ///\e 
   101     Exception() throw() {}
   102   ///\e 
   103     explicit Exception(const std::string &s) throw()
   104       : ErrorMessage(s) {}
   105   ///\e 
   106     virtual ~Exception() throw() {}
   107     
   108   ///\e 
   109     virtual const char* what() const throw() {
   110       const char *mes = message();
   111       if( mes ) return mes;
   112       return "lemon::Exception";
   113     }
   114   };
   115 
   116   ///\e 
   117   class LogicError : public Exception {
   118   ///\e 
   119     explicit LogicError(const std::string &s)
   120       : Exception(s) {}
   121   };
   122 
   123   ///\e 
   124   class RuntimeError : public Exception {
   125   ///\e 
   126     explicit RuntimeError(const std::string &s)
   127       : Exception(s) {}
   128   };
   129 
   130   ///\e 
   131   class RangeError : public RuntimeError {
   132   ///\e 
   133     explicit RangeError(const std::string &s)
   134       : RuntimeError(s) {}
   135   };
   136 
   137   ///\e 
   138   class IOError : public RuntimeError {
   139   ///\e 
   140     explicit IOError(const std::string &s)
   141       : RuntimeError(s) {}
   142   };
   143 
   144   ///\e 
   145   class DataFormatError : public IOError {
   146   ///\e 
   147     explicit DataFormatError(const std::string &message)
   148       : IOError(message) : line(0) {}
   149   ///\e 
   150     DataFormatError(const std::string &file_name, int line_num,
   151 		    const std::string &message)
   152       : IOError(message), line(line_num) { set_file(file_name); }
   153 
   154   ///\e 
   155     void set_line(int line_num) { line=line_num; }
   156   ///\e 
   157     void set_file(const std::string &file_name) {
   158       try {
   159 	file.reset(new std::string);
   160 	*file = file_name;
   161       }
   162       catch(...) {
   163 	file.reset();
   164       }
   165     }
   166 
   167   ///\e 
   168     virtual const char* what() const {
   169       const char *mes = 0;
   170       try {
   171 	std::ostringstream ostr;
   172 	ostr << IOError::what();
   173 	if( file || line ) {
   174 	  ostr << " (";
   175 	  if( file ) ostr << "in file" << *file;
   176 	  if( line ) ostr << " at line" << line;
   177 	}
   178 	mes = ostr.str().c_str();
   179       }
   180       catch(...) {}
   181       if( mes ) return mes;
   182       return "lemon::DataFormatError";
   183     }
   184   };
   185 
   186 
   187 
   188   /****************  Macros  ****************/
   189 
   190 
   191   /**
   192    * \brief Macro for assertions with customizable message
   193    */
   194 
   195 # define lemon_assert(exp, msg) \
   196     if(!(exp)) { \
   197       std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
   198       abort; \
   199     }
   200 
   201 
   202   /**
   203    * \brief Macro for mark not yet implemented features.
   204    *
   205    * \todo Is this the right place for this? It should be used only in
   206    * modules under development.
   207    */
   208 
   209 # define FIXME(msg) lemon_assert(0, "FIXME: " msg)
   210 
   211 }
   212 #endif // LEMON_ERROR_H