# HG changeset patch # User klao # Date 1105058634 0 # Node ID cbc27743e17a8440f2d7c4590327c1a65f56cdd6 # Parent f901ff02b2d7c1200847b946eacdf5ee582d37c1 Exception hierarchy sketch. Exception safe exception classes. diff -r f901ff02b2d7 -r cbc27743e17a src/work/klao/error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/klao/error.h Fri Jan 07 00:43:54 2005 +0000 @@ -0,0 +1,188 @@ +/* -*- C++ -*- + * src/lemon/error.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Combinatorial Optimization Research Group, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_ERROR_H +#define LEMON_ERROR_H + +//! \ingroup misc +//! \file +//! \brief Basic error handling (signaling) routines. + +#include +#include +#include + +#include + +namespace lemon { + + /// Exception-safe convenient "error message" class. + class ErrorMessage { + protected: + boost::shared_ptr buf; + + bool init() throw() { + try { + buf.reset(new std::ostringstream); + } + catch(...) { + buf.reset(); + } + return buf; + } + + public: + + ErrorMessage() throw() { init(); } + + ErrorMessage(const char *message) throw() { + init(); + *this << message; + } + + ErrorMessage(const std::string &message) throw() { + init(); + *this << message; + } + + template + ErrorMessage& operator<<(const T &t) throw() { + if( !buf ) return *this; + + try { + *buf << t; + } + catch(...) { + buf.reset(); + } + } + + const char* message() throw() { + if( !buf ) return 0; + + const char* mes = 0; + try { + mes = buf->str().c_str(); + } + catch(...) {} + return mes; + } + + }; + + /** + * \brief Generic exception class. + * + * Base class for exceptions used in LEMON. + */ + class Exception : public std::exception, public ErrorMessage { + public: + Exception() throw() {} + explicit Exception(const std::string &s) throw() + : ErrorMessage(s) {} + virtual ~Exception() throw() {} + + virtual const char* what() const throw() { + const char *mes = message(); + if( mes ) return mes; + return "lemon::Exception"; + } + }; + + + class LogicError : public Exception { + explicit LogicError(const std::string &s) + : Exception(s) {} + }; + + class RuntimeError : public Exception { + explicit RuntimeError(const std::string &s) + : Exception(s) {} + }; + + class RangeError : public RuntimeError { + explicit RangeError(const std::string &s) + : RuntimeError(s) {} + }; + + class IOError : public RuntimeError { + explicit IOError(const std::string &s) + : RuntimeError(s) {} + }; + + class DataFormatError : public IOError { + explicit DataFormatError(const std::string &message) + : IOError(message) : line(0) {} + DataFormatError(const std::string &file_name, int line_num, + sconst std::string &message) + : IOError(message), line(line_num) { set_file(file_name); } + + void set_line(int line_num) { line=line_num; } + void set_file(const std::string &file_name) { + try { + file.reset(new std::string); + *file = file_name; + } + catch(...) { + file.reset(); + } + } + + virtual const char* what() const { + const char *mes = 0; + try { + std::ostringstream ostr; + ostr << IOError::what(); + if( file || line ) { + ostr << " ("; + if( file ) ostr << "in file" << *file; + if( line ) ostr << " at line" << line; + } + mes = ostr.str().c_str(); + } + catch(...) {} + if( mes ) return mes; + return "lemon::DataFormatError"; + } + }; + + + + /**************** Macros ****************/ + + + /** + * \brief Macro for assertions with customizable message + */ + +# define lemon_assert(exp, msg) \ + if(!(exp)) { \ + std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \ + abort; \ + } + + + /** + * \brief Macro for mark not yet implemented features. + * + * \todo Is this the right place for this? It should be used only in + * modules under development. + */ + +# define FIXME(msg) lemon_assert(0, "FIXME: " msg) + +} +#endif // LEMON_ERROR_H