1.1 --- a/src/work/klao/error.h Thu Feb 03 19:27:10 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,387 +0,0 @@
1.4 -/* -*- C++ -*-
1.5 - * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
1.6 - *
1.7 - * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 - * (Egervary Combinatorial Optimization Research Group, EGRES).
1.9 - *
1.10 - * Permission to use, modify and distribute this software is granted
1.11 - * provided that this copyright notice appears in all copies. For
1.12 - * precise terms see the accompanying LICENSE file.
1.13 - *
1.14 - * This software is provided "AS IS" with no warranty of any kind,
1.15 - * express or implied, and with no claim as to its suitability for any
1.16 - * purpose.
1.17 - *
1.18 - */
1.19 -
1.20 -#ifndef LEMON_ERROR_H
1.21 -#define LEMON_ERROR_H
1.22 -
1.23 -//! \ingroup misc
1.24 -//! \file
1.25 -//! \brief Basic exception classes and error handling.
1.26 -
1.27 -#include <exception>
1.28 -#include <string>
1.29 -#include <sstream>
1.30 -#include <iostream>
1.31 -#include <cstdlib>
1.32 -
1.33 -#include <boost/shared_ptr.hpp>
1.34 -
1.35 -namespace lemon {
1.36 -
1.37 - /// Exception-safe convenient "error message" class.
1.38 -
1.39 - /// Helper class which provides a convenient ostream-like (operator <<
1.40 - /// based) interface to create a string message. Mostly useful in
1.41 - /// exception classes (therefore the name).
1.42 - class ErrorMessage {
1.43 - protected:
1.44 - ///\e
1.45 - boost::shared_ptr<std::ostringstream> buf;
1.46 -
1.47 - ///\e
1.48 - bool init() throw() {
1.49 - try {
1.50 - buf.reset(new std::ostringstream);
1.51 - }
1.52 - catch(...) {
1.53 - buf.reset();
1.54 - }
1.55 - return buf;
1.56 - }
1.57 -
1.58 - public:
1.59 -
1.60 - ///\e
1.61 - ErrorMessage() throw() { init(); }
1.62 -
1.63 - ///\e
1.64 - ErrorMessage(const char *message) throw() {
1.65 - init();
1.66 - *this << message;
1.67 - }
1.68 -
1.69 - ///\e
1.70 - ErrorMessage(const std::string &message) throw() {
1.71 - init();
1.72 - *this << message;
1.73 - }
1.74 -
1.75 - ///\e
1.76 - template <typename T>
1.77 - ErrorMessage& operator<<(const T &t) throw() {
1.78 - if( !buf ) return *this;
1.79 -
1.80 - try {
1.81 - *buf << t;
1.82 - }
1.83 - catch(...) {
1.84 - buf.reset();
1.85 - }
1.86 - }
1.87 -
1.88 - ///\e
1.89 - const char* message() throw() {
1.90 - if( !buf ) return 0;
1.91 -
1.92 - const char* mes = 0;
1.93 - try {
1.94 - mes = buf->str().c_str();
1.95 - }
1.96 - catch(...) {}
1.97 - return mes;
1.98 - }
1.99 -
1.100 - };
1.101 -
1.102 - /**
1.103 - * \brief Generic exception class.
1.104 - *
1.105 - * Base class for exceptions used in LEMON.
1.106 - */
1.107 - class Exception : public std::exception {
1.108 - public:
1.109 - ///\e
1.110 - Exception() {}
1.111 - ///\e
1.112 - virtual ~Exception() throw() {}
1.113 -
1.114 - ///\e
1.115 - virtual const char* exceptionName() const {
1.116 - return "lemon::Exception";
1.117 - }
1.118 -
1.119 - ///\e
1.120 - virtual const char* what() const throw() {
1.121 - return exceptionName();
1.122 - }
1.123 - };
1.124 -
1.125 - /**
1.126 - * \brief One of the two main subclasses of \ref Exception.
1.127 - *
1.128 - * Logic errors represent problems in the internal logic of a program;
1.129 - * in theory, these are preventable, and even detectable before the
1.130 - * program runs (e.g., violations of class invariants).
1.131 - *
1.132 - * For a typical example \see UninitializedParameterError.
1.133 - */
1.134 - class LogicError : public Exception {
1.135 - public:
1.136 - virtual const char* exceptionName() const {
1.137 - return "lemon::LogicError";
1.138 - }
1.139 - };
1.140 -
1.141 -
1.142 - /**
1.143 - * \brief One of the two main subclasses of \ref Exception.
1.144 - *
1.145 - * Runtime errors represent problems outside the scope of a program;
1.146 - * they cannot be easily predicted and can generally only be caught as
1.147 - * the program executes.
1.148 - */
1.149 - class RuntimeError : public Exception {
1.150 - public:
1.151 - virtual const char* exceptionName() const {
1.152 - return "lemon::RuntimeError";
1.153 - }
1.154 - };
1.155 -
1.156 - ///\e
1.157 - class RangeError : public RuntimeError {
1.158 - public:
1.159 - virtual const char* exceptionName() const {
1.160 - return "lemon::RangeError";
1.161 - }
1.162 - };
1.163 -
1.164 - ///\e
1.165 - class IOError : public RuntimeError {
1.166 - public:
1.167 - virtual const char* exceptionName() const {
1.168 - return "lemon::IOError";
1.169 - }
1.170 - };
1.171 -
1.172 - ///\e
1.173 - class DataFormatError : public IOError {
1.174 - protected:
1.175 - const char *_message;
1.176 - int _line;
1.177 - boost::shared_ptr<std::string> _file;
1.178 -
1.179 - public:
1.180 - ///\e
1.181 - explicit DataFormatError(const char *the_message)
1.182 - : _message(the_message), _line(0) {}
1.183 - ///\e
1.184 - DataFormatError(const std::string &file_name, int line_num,
1.185 - const char *the_message)
1.186 - : _message(the_message), _line(line_num) { file(file_name); }
1.187 -
1.188 - ///\e
1.189 - void line(int line_num) { _line=line_num; }
1.190 - ///\e
1.191 - void message(char *the_message) { _message=the_message; }
1.192 - ///\e
1.193 - void file(const std::string &file_name) {
1.194 - try {
1.195 - _file.reset(new std::string);
1.196 - *_file = file_name;
1.197 - }
1.198 - catch(...) {
1.199 - _file.reset();
1.200 - }
1.201 - }
1.202 -
1.203 - ///\e
1.204 - int line() const { return _line; }
1.205 - ///\e
1.206 - const char* message() const { return _message; }
1.207 -
1.208 - /// \brief Returns the filename.
1.209 - ///
1.210 - /// Returns \e "(unknown)" if the filename was not specified.
1.211 - const char* file() const {
1.212 - if( _file )
1.213 - return _file->c_str();
1.214 - else
1.215 - return "(unknown)";
1.216 - }
1.217 -
1.218 - ///\e
1.219 - virtual const char* what() const throw() {
1.220 - const char *mes = 0;
1.221 - try {
1.222 - std::ostringstream ostr;
1.223 - ostr << _message;
1.224 - if( _file || _line ) {
1.225 - ostr << " (";
1.226 - if( _file ) ostr << "in file '" << *_file << "'";
1.227 - if( _file && _line ) ostr << " ";
1.228 - if( _line ) ostr << "at line " << _line;
1.229 - ostr << ")";
1.230 - }
1.231 - mes = ostr.str().c_str();
1.232 - }
1.233 - catch(...) {}
1.234 - if( mes ) return mes;
1.235 - return exceptionName();
1.236 - }
1.237 -
1.238 - virtual const char* exceptionName() const {
1.239 - return "lemon::DataFormatError";
1.240 - }
1.241 -
1.242 - virtual ~DataFormatError() throw() {}
1.243 - };
1.244 -
1.245 -
1.246 - ///\e
1.247 - class AssertionFailedError : public LogicError {
1.248 - protected:
1.249 - const char *assertion;
1.250 - const char *file;
1.251 - int line;
1.252 - const char *function;
1.253 - const char *message;
1.254 - public:
1.255 - ///\e
1.256 - AssertionFailedError(const char *_file, int _line, const char *func,
1.257 - const char *msg, const char *_assertion = 0) :
1.258 - assertion(_assertion), file(_file), line(_line), function(func),
1.259 - message(msg) {}
1.260 -
1.261 - ///\e
1.262 - const char* get_assertion() const { return assertion; }
1.263 - ///\e
1.264 - const char* get_message() const { return message; }
1.265 - ///\e
1.266 - const char* get_file() const { return file; }
1.267 - ///\e
1.268 - const char* get_function() const { return function; }
1.269 - ///\e
1.270 - int get_line() const { return line; }
1.271 -
1.272 -
1.273 - virtual const char* what() const throw() {
1.274 - const char *mes = 0;
1.275 - try {
1.276 - std::ostringstream ostr;
1.277 - ostr << file << ":" << line << ": ";
1.278 - if( function )
1.279 - ostr << function << ": ";
1.280 - ostr << message;
1.281 - if( assertion )
1.282 - ostr << " (assertion '" << assertion << "' failed)";
1.283 - mes = ostr.str().c_str();
1.284 - }
1.285 - catch(...) {}
1.286 - if( mes ) return mes;
1.287 - return exceptionName();
1.288 - }
1.289 -
1.290 - virtual const char* exceptionName() const {
1.291 - return "lemon::AssertionFailedError";
1.292 - }
1.293 -
1.294 - virtual ~AssertionFailedError() throw() {}
1.295 - };
1.296 -
1.297 -
1.298 - /**************** Macros ****************/
1.299 -
1.300 -
1.301 - inline
1.302 - void assert_fail(const char *file, int line, const char *func,
1.303 - const char *message, const char *assertion = 0,
1.304 - bool do_abort=true)
1.305 - {
1.306 - using namespace std;
1.307 - cerr << file << ":" << line << ": ";
1.308 - if( func )
1.309 - cerr << func << ": ";
1.310 - cerr << message;
1.311 - if( assertion )
1.312 - cerr << " (assertion '" << assertion << "' failed)";
1.313 - cerr << endl;
1.314 - if(do_abort)
1.315 - abort();
1.316 - }
1.317 -
1.318 - inline
1.319 - void assert_fail_throw(const char *file, int line, const char *func,
1.320 - const char *message, const char *assertion = 0,
1.321 - bool = true)
1.322 - {
1.323 - throw AssertionFailedError(file, line, func, message, assertion);
1.324 - }
1.325 -
1.326 -
1.327 -}
1.328 -#endif // LEMON_ERROR_H
1.329 -
1.330 -#undef LEMON_ASSERT
1.331 -#undef LEMON_FIXME
1.332 -
1.333 -#ifndef LEMON_ASSERT_ABORT
1.334 -# define LEMON_ASSERT_ABORT 1
1.335 -#endif
1.336 -
1.337 -#ifndef LEMON_ASSERT_HANDLER
1.338 -# ifdef LEMON_ASSERT_EXCEPTION
1.339 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_throw
1.340 -# else
1.341 -# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
1.342 -# endif
1.343 -#endif
1.344 -
1.345 -#if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
1.346 -
1.347 -# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
1.348 -
1.349 -#else
1.350 -
1.351 -/**
1.352 - * \brief Macro for assertions with customizable message
1.353 - *
1.354 - * Macro for assertions with customizable message.
1.355 - *
1.356 - * The behaviour can be customized with LEMON_ASSERT_HANDLER,
1.357 - * LEMON_ASSERT_EXCEPTION and LEMON_ASSERT_ABORT defines. Asserts can be
1.358 - * disabled by defining either NDEBUG or LEMON_DISABLE_ASSERTS macros.
1.359 - *
1.360 - * \todo We should provide some way to reset to the default behaviour,
1.361 - * shouldn't we?
1.362 - *
1.363 - * \todo This whole 'assert' business should be placed in a separate
1.364 - * include file.
1.365 - *
1.366 - * \todo __PRETTY_FUNCTION__ should be replaced by something
1.367 - * compiler-independant, like BOOST_CURRENT_FUNCTION
1.368 - */
1.369 -
1.370 -# define LEMON_ASSERT(exp, msg) \
1.371 - (static_cast<void> (!!(exp) ? 0 : ( \
1.372 - LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
1.373 - __PRETTY_FUNCTION__, \
1.374 - (msg), #exp, LEMON_ASSERT_ABORT), 0)))
1.375 -
1.376 -#endif // NDEBUG || LEMON_DISABLE_ASSERTS
1.377 -
1.378 -/**
1.379 - * \brief Macro for mark not yet implemented features.
1.380 - *
1.381 - * \todo Is this the right place for this? It should be used only in
1.382 - * modules under development.
1.383 - *
1.384 - * \todo __PRETTY_FUNCTION__ should be replaced by something
1.385 - * compiler-independant, like BOOST_CURRENT_FUNCTION
1.386 - */
1.387 -
1.388 -# define LEMON_FIXME(msg) \
1.389 - (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
1.390 - "FIXME: " msg))