alpar@906
|
1 |
/* -*- C++ -*-
|
alpar@921
|
2 |
* src/lemon/error.h - Part of LEMON, a generic C++ optimization library
|
alpar@906
|
3 |
*
|
alpar@906
|
4 |
* Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
alpar@906
|
5 |
* (Egervary Combinatorial Optimization Research Group, EGRES).
|
alpar@906
|
6 |
*
|
alpar@906
|
7 |
* Permission to use, modify and distribute this software is granted
|
alpar@906
|
8 |
* provided that this copyright notice appears in all copies. For
|
alpar@906
|
9 |
* precise terms see the accompanying LICENSE file.
|
alpar@906
|
10 |
*
|
alpar@906
|
11 |
* This software is provided "AS IS" with no warranty of any kind,
|
alpar@906
|
12 |
* express or implied, and with no claim as to its suitability for any
|
alpar@906
|
13 |
* purpose.
|
alpar@906
|
14 |
*
|
alpar@906
|
15 |
*/
|
alpar@883
|
16 |
|
alpar@921
|
17 |
#ifndef LEMON_ERROR_H
|
alpar@921
|
18 |
#define LEMON_ERROR_H
|
alpar@883
|
19 |
|
alpar@883
|
20 |
//! \ingroup misc
|
alpar@883
|
21 |
//! \file
|
alpar@883
|
22 |
//! \brief Basic error handling (signaling) routines.
|
alpar@883
|
23 |
|
alpar@883
|
24 |
#include <exception>
|
alpar@883
|
25 |
#include <string>
|
alpar@883
|
26 |
#include <sstream>
|
alpar@883
|
27 |
|
klao@1056
|
28 |
#include <boost/shared_ptr.hpp>
|
alpar@883
|
29 |
|
alpar@921
|
30 |
namespace lemon {
|
alpar@883
|
31 |
|
klao@1056
|
32 |
/// Exception-safe convenient "error message" class.
|
klao@1056
|
33 |
class ErrorMessage {
|
klao@1056
|
34 |
protected:
|
klao@1056
|
35 |
boost::shared_ptr<std::ostringstream> buf;
|
klao@1056
|
36 |
|
klao@1056
|
37 |
bool init() throw() {
|
klao@1056
|
38 |
try {
|
klao@1056
|
39 |
buf.reset(new std::ostringstream);
|
klao@1056
|
40 |
}
|
klao@1056
|
41 |
catch(...) {
|
klao@1056
|
42 |
buf.reset();
|
klao@1056
|
43 |
}
|
klao@1056
|
44 |
return buf;
|
klao@1056
|
45 |
}
|
klao@1056
|
46 |
|
klao@1056
|
47 |
public:
|
klao@1056
|
48 |
|
klao@1056
|
49 |
ErrorMessage() throw() { init(); }
|
klao@1056
|
50 |
|
klao@1056
|
51 |
ErrorMessage(const char *message) throw() {
|
klao@1056
|
52 |
init();
|
klao@1056
|
53 |
*this << message;
|
klao@1056
|
54 |
}
|
klao@1056
|
55 |
|
klao@1056
|
56 |
ErrorMessage(const std::string &message) throw() {
|
klao@1056
|
57 |
init();
|
klao@1056
|
58 |
*this << message;
|
klao@1056
|
59 |
}
|
klao@1056
|
60 |
|
klao@1056
|
61 |
template <typename T>
|
klao@1056
|
62 |
ErrorMessage& operator<<(const T &t) throw() {
|
klao@1056
|
63 |
if( !buf ) return *this;
|
klao@1056
|
64 |
|
klao@1056
|
65 |
try {
|
klao@1056
|
66 |
*buf << t;
|
klao@1056
|
67 |
}
|
klao@1056
|
68 |
catch(...) {
|
klao@1056
|
69 |
buf.reset();
|
klao@1056
|
70 |
}
|
klao@1056
|
71 |
}
|
klao@1056
|
72 |
|
klao@1056
|
73 |
const char* message() throw() {
|
klao@1056
|
74 |
if( !buf ) return 0;
|
klao@1056
|
75 |
|
klao@1056
|
76 |
const char* mes = 0;
|
klao@1056
|
77 |
try {
|
klao@1056
|
78 |
mes = buf->str().c_str();
|
klao@1056
|
79 |
}
|
klao@1056
|
80 |
catch(...) {}
|
klao@1056
|
81 |
return mes;
|
klao@1056
|
82 |
}
|
klao@1056
|
83 |
|
klao@1056
|
84 |
};
|
klao@1056
|
85 |
|
alpar@883
|
86 |
/**
|
alpar@883
|
87 |
* \brief Generic exception class.
|
alpar@883
|
88 |
*
|
klao@1056
|
89 |
* Base class for exceptions used in LEMON.
|
alpar@883
|
90 |
*/
|
klao@1056
|
91 |
class Exception : public std::exception, public ErrorMessage {
|
alpar@883
|
92 |
public:
|
klao@1056
|
93 |
Exception() throw() {}
|
klao@1056
|
94 |
explicit Exception(const std::string &s) throw()
|
klao@1056
|
95 |
: ErrorMessage(s) {}
|
alpar@883
|
96 |
virtual ~Exception() throw() {}
|
alpar@883
|
97 |
|
alpar@883
|
98 |
virtual const char* what() const throw() {
|
klao@1056
|
99 |
const char *mes = message();
|
klao@1056
|
100 |
if( mes ) return mes;
|
klao@1056
|
101 |
return "lemon::Exception";
|
klao@1056
|
102 |
}
|
klao@1056
|
103 |
};
|
klao@1056
|
104 |
|
klao@1056
|
105 |
|
klao@1056
|
106 |
class LogicError : public Exception {
|
klao@1056
|
107 |
explicit LogicError(const std::string &s)
|
klao@1056
|
108 |
: Exception(s) {}
|
klao@1056
|
109 |
};
|
klao@1056
|
110 |
|
klao@1056
|
111 |
class RuntimeError : public Exception {
|
klao@1056
|
112 |
explicit RuntimeError(const std::string &s)
|
klao@1056
|
113 |
: Exception(s) {}
|
klao@1056
|
114 |
};
|
klao@1056
|
115 |
|
klao@1056
|
116 |
class RangeError : public RuntimeError {
|
klao@1056
|
117 |
explicit RangeError(const std::string &s)
|
klao@1056
|
118 |
: RuntimeError(s) {}
|
klao@1056
|
119 |
};
|
klao@1056
|
120 |
|
klao@1056
|
121 |
class IOError : public RuntimeError {
|
klao@1056
|
122 |
explicit IOError(const std::string &s)
|
klao@1056
|
123 |
: RuntimeError(s) {}
|
klao@1056
|
124 |
};
|
klao@1056
|
125 |
|
klao@1056
|
126 |
class DataFormatError : public IOError {
|
klao@1056
|
127 |
explicit DataFormatError(const std::string &message)
|
klao@1056
|
128 |
: IOError(message) : line(0) {}
|
klao@1056
|
129 |
DataFormatError(const std::string &file_name, int line_num,
|
klao@1056
|
130 |
sconst std::string &message)
|
klao@1056
|
131 |
: IOError(message), line(line_num) { set_file(file_name); }
|
klao@1056
|
132 |
|
klao@1056
|
133 |
void set_line(int line_num) { line=line_num; }
|
klao@1056
|
134 |
void set_file(const std::string &file_name) {
|
klao@1056
|
135 |
try {
|
klao@1056
|
136 |
file.reset(new std::string);
|
klao@1056
|
137 |
*file = file_name;
|
klao@1056
|
138 |
}
|
klao@1056
|
139 |
catch(...) {
|
klao@1056
|
140 |
file.reset();
|
klao@1056
|
141 |
}
|
alpar@883
|
142 |
}
|
alpar@883
|
143 |
|
klao@1056
|
144 |
virtual const char* what() const {
|
klao@1056
|
145 |
const char *mes = 0;
|
klao@1056
|
146 |
try {
|
klao@1056
|
147 |
std::ostringstream ostr;
|
klao@1056
|
148 |
ostr << IOError::what();
|
klao@1056
|
149 |
if( file || line ) {
|
klao@1056
|
150 |
ostr << " (";
|
klao@1056
|
151 |
if( file ) ostr << "in file" << *file;
|
klao@1056
|
152 |
if( line ) ostr << " at line" << line;
|
klao@1056
|
153 |
}
|
klao@1056
|
154 |
mes = ostr.str().c_str();
|
klao@1056
|
155 |
}
|
klao@1056
|
156 |
catch(...) {}
|
klao@1056
|
157 |
if( mes ) return mes;
|
klao@1056
|
158 |
return "lemon::DataFormatError";
|
klao@1056
|
159 |
}
|
alpar@883
|
160 |
};
|
alpar@883
|
161 |
|
klao@1056
|
162 |
|
klao@1056
|
163 |
|
klao@1056
|
164 |
/**************** Macros ****************/
|
klao@1056
|
165 |
|
klao@1056
|
166 |
|
alpar@883
|
167 |
/**
|
klao@1056
|
168 |
* \brief Macro for assertions with customizable message
|
alpar@883
|
169 |
*/
|
klao@1056
|
170 |
|
klao@1056
|
171 |
# define lemon_assert(exp, msg) \
|
klao@1056
|
172 |
if(!(exp)) { \
|
klao@1056
|
173 |
std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
|
klao@1056
|
174 |
abort; \
|
klao@1056
|
175 |
}
|
klao@1056
|
176 |
|
alpar@883
|
177 |
|
alpar@883
|
178 |
/**
|
alpar@883
|
179 |
* \brief Macro for mark not yet implemented features.
|
alpar@883
|
180 |
*
|
alpar@883
|
181 |
* \todo Is this the right place for this? It should be used only in
|
alpar@883
|
182 |
* modules under development.
|
alpar@883
|
183 |
*/
|
alpar@883
|
184 |
|
klao@1056
|
185 |
# define FIXME(msg) lemon_assert(0, "FIXME: " msg)
|
alpar@883
|
186 |
|
alpar@883
|
187 |
}
|
alpar@921
|
188 |
#endif // LEMON_ERROR_H
|