Exception hierarchy sketch.
Exception safe exception classes.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/work/klao/error.h Fri Jan 07 00:43:54 2005 +0000
1.3 @@ -0,0 +1,188 @@
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 error handling (signaling) routines.
1.26 +
1.27 +#include <exception>
1.28 +#include <string>
1.29 +#include <sstream>
1.30 +
1.31 +#include <boost/shared_ptr.hpp>
1.32 +
1.33 +namespace lemon {
1.34 +
1.35 + /// Exception-safe convenient "error message" class.
1.36 + class ErrorMessage {
1.37 + protected:
1.38 + boost::shared_ptr<std::ostringstream> buf;
1.39 +
1.40 + bool init() throw() {
1.41 + try {
1.42 + buf.reset(new std::ostringstream);
1.43 + }
1.44 + catch(...) {
1.45 + buf.reset();
1.46 + }
1.47 + return buf;
1.48 + }
1.49 +
1.50 + public:
1.51 +
1.52 + ErrorMessage() throw() { init(); }
1.53 +
1.54 + ErrorMessage(const char *message) throw() {
1.55 + init();
1.56 + *this << message;
1.57 + }
1.58 +
1.59 + ErrorMessage(const std::string &message) throw() {
1.60 + init();
1.61 + *this << message;
1.62 + }
1.63 +
1.64 + template <typename T>
1.65 + ErrorMessage& operator<<(const T &t) throw() {
1.66 + if( !buf ) return *this;
1.67 +
1.68 + try {
1.69 + *buf << t;
1.70 + }
1.71 + catch(...) {
1.72 + buf.reset();
1.73 + }
1.74 + }
1.75 +
1.76 + const char* message() throw() {
1.77 + if( !buf ) return 0;
1.78 +
1.79 + const char* mes = 0;
1.80 + try {
1.81 + mes = buf->str().c_str();
1.82 + }
1.83 + catch(...) {}
1.84 + return mes;
1.85 + }
1.86 +
1.87 + };
1.88 +
1.89 + /**
1.90 + * \brief Generic exception class.
1.91 + *
1.92 + * Base class for exceptions used in LEMON.
1.93 + */
1.94 + class Exception : public std::exception, public ErrorMessage {
1.95 + public:
1.96 + Exception() throw() {}
1.97 + explicit Exception(const std::string &s) throw()
1.98 + : ErrorMessage(s) {}
1.99 + virtual ~Exception() throw() {}
1.100 +
1.101 + virtual const char* what() const throw() {
1.102 + const char *mes = message();
1.103 + if( mes ) return mes;
1.104 + return "lemon::Exception";
1.105 + }
1.106 + };
1.107 +
1.108 +
1.109 + class LogicError : public Exception {
1.110 + explicit LogicError(const std::string &s)
1.111 + : Exception(s) {}
1.112 + };
1.113 +
1.114 + class RuntimeError : public Exception {
1.115 + explicit RuntimeError(const std::string &s)
1.116 + : Exception(s) {}
1.117 + };
1.118 +
1.119 + class RangeError : public RuntimeError {
1.120 + explicit RangeError(const std::string &s)
1.121 + : RuntimeError(s) {}
1.122 + };
1.123 +
1.124 + class IOError : public RuntimeError {
1.125 + explicit IOError(const std::string &s)
1.126 + : RuntimeError(s) {}
1.127 + };
1.128 +
1.129 + class DataFormatError : public IOError {
1.130 + explicit DataFormatError(const std::string &message)
1.131 + : IOError(message) : line(0) {}
1.132 + DataFormatError(const std::string &file_name, int line_num,
1.133 + sconst std::string &message)
1.134 + : IOError(message), line(line_num) { set_file(file_name); }
1.135 +
1.136 + void set_line(int line_num) { line=line_num; }
1.137 + void set_file(const std::string &file_name) {
1.138 + try {
1.139 + file.reset(new std::string);
1.140 + *file = file_name;
1.141 + }
1.142 + catch(...) {
1.143 + file.reset();
1.144 + }
1.145 + }
1.146 +
1.147 + virtual const char* what() const {
1.148 + const char *mes = 0;
1.149 + try {
1.150 + std::ostringstream ostr;
1.151 + ostr << IOError::what();
1.152 + if( file || line ) {
1.153 + ostr << " (";
1.154 + if( file ) ostr << "in file" << *file;
1.155 + if( line ) ostr << " at line" << line;
1.156 + }
1.157 + mes = ostr.str().c_str();
1.158 + }
1.159 + catch(...) {}
1.160 + if( mes ) return mes;
1.161 + return "lemon::DataFormatError";
1.162 + }
1.163 + };
1.164 +
1.165 +
1.166 +
1.167 + /**************** Macros ****************/
1.168 +
1.169 +
1.170 + /**
1.171 + * \brief Macro for assertions with customizable message
1.172 + */
1.173 +
1.174 +# define lemon_assert(exp, msg) \
1.175 + if(!(exp)) { \
1.176 + std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
1.177 + abort; \
1.178 + }
1.179 +
1.180 +
1.181 + /**
1.182 + * \brief Macro for mark not yet implemented features.
1.183 + *
1.184 + * \todo Is this the right place for this? It should be used only in
1.185 + * modules under development.
1.186 + */
1.187 +
1.188 +# define FIXME(msg) lemon_assert(0, "FIXME: " msg)
1.189 +
1.190 +}
1.191 +#endif // LEMON_ERROR_H