/* -*- 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: ///\e boost::shared_ptr buf; ///\e bool init() throw() { try { buf.reset(new std::ostringstream); } catch(...) { buf.reset(); } return buf; } public: ///\e ErrorMessage() throw() { init(); } ///\e ErrorMessage(const char *message) throw() { init(); *this << message; } ///\e ErrorMessage(const std::string &message) throw() { init(); *this << message; } ///\e template ErrorMessage& operator<<(const T &t) throw() { if( !buf ) return *this; try { *buf << t; } catch(...) { buf.reset(); } } ///\e 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: ///\e Exception() throw() {} ///\e explicit Exception(const std::string &s) throw() : ErrorMessage(s) {} ///\e virtual ~Exception() throw() {} ///\e virtual const char* what() const throw() { const char *mes = message(); if( mes ) return mes; return "lemon::Exception"; } }; ///\e class LogicError : public Exception { ///\e explicit LogicError(const std::string &s) : Exception(s) {} }; ///\e class RuntimeError : public Exception { ///\e explicit RuntimeError(const std::string &s) : Exception(s) {} }; ///\e class RangeError : public RuntimeError { ///\e explicit RangeError(const std::string &s) : RuntimeError(s) {} }; ///\e class IOError : public RuntimeError { ///\e explicit IOError(const std::string &s) : RuntimeError(s) {} }; ///\e class DataFormatError : public IOError { ///\e explicit DataFormatError(const std::string &message) : IOError(message) : line(0) {} ///\e DataFormatError(const std::string &file_name, int line_num, const std::string &message) : IOError(message), line(line_num) { set_file(file_name); } ///\e void set_line(int line_num) { line=line_num; } ///\e void set_file(const std::string &file_name) { try { file.reset(new std::string); *file = file_name; } catch(...) { file.reset(); } } ///\e 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