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:
|
alpar@1061
|
35 |
///\e
|
klao@1056
|
36 |
boost::shared_ptr<std::ostringstream> buf;
|
klao@1056
|
37 |
|
alpar@1061
|
38 |
///\e
|
klao@1056
|
39 |
bool init() throw() {
|
klao@1056
|
40 |
try {
|
klao@1056
|
41 |
buf.reset(new std::ostringstream);
|
klao@1056
|
42 |
}
|
klao@1056
|
43 |
catch(...) {
|
klao@1056
|
44 |
buf.reset();
|
klao@1056
|
45 |
}
|
klao@1056
|
46 |
return buf;
|
klao@1056
|
47 |
}
|
klao@1056
|
48 |
|
klao@1056
|
49 |
public:
|
klao@1056
|
50 |
|
alpar@1061
|
51 |
///\e
|
klao@1056
|
52 |
ErrorMessage() throw() { init(); }
|
klao@1056
|
53 |
|
alpar@1061
|
54 |
///\e
|
klao@1056
|
55 |
ErrorMessage(const char *message) throw() {
|
klao@1056
|
56 |
init();
|
klao@1056
|
57 |
*this << message;
|
klao@1056
|
58 |
}
|
klao@1056
|
59 |
|
alpar@1061
|
60 |
///\e
|
klao@1056
|
61 |
ErrorMessage(const std::string &message) throw() {
|
klao@1056
|
62 |
init();
|
klao@1056
|
63 |
*this << message;
|
klao@1056
|
64 |
}
|
klao@1056
|
65 |
|
alpar@1061
|
66 |
///\e
|
klao@1056
|
67 |
template <typename T>
|
klao@1056
|
68 |
ErrorMessage& operator<<(const T &t) throw() {
|
klao@1056
|
69 |
if( !buf ) return *this;
|
klao@1056
|
70 |
|
klao@1056
|
71 |
try {
|
klao@1056
|
72 |
*buf << t;
|
klao@1056
|
73 |
}
|
klao@1056
|
74 |
catch(...) {
|
klao@1056
|
75 |
buf.reset();
|
klao@1056
|
76 |
}
|
klao@1056
|
77 |
}
|
klao@1056
|
78 |
|
alpar@1061
|
79 |
///\e
|
klao@1056
|
80 |
const char* message() throw() {
|
klao@1056
|
81 |
if( !buf ) return 0;
|
klao@1056
|
82 |
|
klao@1056
|
83 |
const char* mes = 0;
|
klao@1056
|
84 |
try {
|
klao@1056
|
85 |
mes = buf->str().c_str();
|
klao@1056
|
86 |
}
|
klao@1056
|
87 |
catch(...) {}
|
klao@1056
|
88 |
return mes;
|
klao@1056
|
89 |
}
|
klao@1056
|
90 |
|
klao@1056
|
91 |
};
|
klao@1056
|
92 |
|
alpar@883
|
93 |
/**
|
alpar@883
|
94 |
* \brief Generic exception class.
|
alpar@883
|
95 |
*
|
klao@1056
|
96 |
* Base class for exceptions used in LEMON.
|
alpar@883
|
97 |
*/
|
klao@1056
|
98 |
class Exception : public std::exception, public ErrorMessage {
|
alpar@883
|
99 |
public:
|
alpar@1061
|
100 |
///\e
|
klao@1056
|
101 |
Exception() throw() {}
|
alpar@1061
|
102 |
///\e
|
klao@1056
|
103 |
explicit Exception(const std::string &s) throw()
|
klao@1056
|
104 |
: ErrorMessage(s) {}
|
alpar@1061
|
105 |
///\e
|
alpar@883
|
106 |
virtual ~Exception() throw() {}
|
alpar@883
|
107 |
|
alpar@1061
|
108 |
///\e
|
alpar@883
|
109 |
virtual const char* what() const throw() {
|
klao@1056
|
110 |
const char *mes = message();
|
klao@1056
|
111 |
if( mes ) return mes;
|
klao@1056
|
112 |
return "lemon::Exception";
|
klao@1056
|
113 |
}
|
klao@1056
|
114 |
};
|
klao@1056
|
115 |
|
alpar@1061
|
116 |
///\e
|
klao@1056
|
117 |
class LogicError : public Exception {
|
alpar@1061
|
118 |
///\e
|
klao@1056
|
119 |
explicit LogicError(const std::string &s)
|
klao@1056
|
120 |
: Exception(s) {}
|
klao@1056
|
121 |
};
|
klao@1056
|
122 |
|
alpar@1061
|
123 |
///\e
|
klao@1056
|
124 |
class RuntimeError : public Exception {
|
alpar@1061
|
125 |
///\e
|
klao@1056
|
126 |
explicit RuntimeError(const std::string &s)
|
klao@1056
|
127 |
: Exception(s) {}
|
klao@1056
|
128 |
};
|
klao@1056
|
129 |
|
alpar@1061
|
130 |
///\e
|
klao@1056
|
131 |
class RangeError : public RuntimeError {
|
alpar@1061
|
132 |
///\e
|
klao@1056
|
133 |
explicit RangeError(const std::string &s)
|
klao@1056
|
134 |
: RuntimeError(s) {}
|
klao@1056
|
135 |
};
|
klao@1056
|
136 |
|
alpar@1061
|
137 |
///\e
|
klao@1056
|
138 |
class IOError : public RuntimeError {
|
alpar@1061
|
139 |
///\e
|
klao@1056
|
140 |
explicit IOError(const std::string &s)
|
klao@1056
|
141 |
: RuntimeError(s) {}
|
klao@1056
|
142 |
};
|
klao@1056
|
143 |
|
alpar@1061
|
144 |
///\e
|
klao@1056
|
145 |
class DataFormatError : public IOError {
|
alpar@1061
|
146 |
///\e
|
klao@1056
|
147 |
explicit DataFormatError(const std::string &message)
|
klao@1056
|
148 |
: IOError(message) : line(0) {}
|
alpar@1061
|
149 |
///\e
|
klao@1056
|
150 |
DataFormatError(const std::string &file_name, int line_num,
|
alpar@1061
|
151 |
const std::string &message)
|
klao@1056
|
152 |
: IOError(message), line(line_num) { set_file(file_name); }
|
klao@1056
|
153 |
|
alpar@1061
|
154 |
///\e
|
klao@1056
|
155 |
void set_line(int line_num) { line=line_num; }
|
alpar@1061
|
156 |
///\e
|
klao@1056
|
157 |
void set_file(const std::string &file_name) {
|
klao@1056
|
158 |
try {
|
klao@1056
|
159 |
file.reset(new std::string);
|
klao@1056
|
160 |
*file = file_name;
|
klao@1056
|
161 |
}
|
klao@1056
|
162 |
catch(...) {
|
klao@1056
|
163 |
file.reset();
|
klao@1056
|
164 |
}
|
alpar@883
|
165 |
}
|
alpar@883
|
166 |
|
alpar@1061
|
167 |
///\e
|
klao@1056
|
168 |
virtual const char* what() const {
|
klao@1056
|
169 |
const char *mes = 0;
|
klao@1056
|
170 |
try {
|
klao@1056
|
171 |
std::ostringstream ostr;
|
klao@1056
|
172 |
ostr << IOError::what();
|
klao@1056
|
173 |
if( file || line ) {
|
klao@1056
|
174 |
ostr << " (";
|
klao@1056
|
175 |
if( file ) ostr << "in file" << *file;
|
klao@1056
|
176 |
if( line ) ostr << " at line" << line;
|
klao@1056
|
177 |
}
|
klao@1056
|
178 |
mes = ostr.str().c_str();
|
klao@1056
|
179 |
}
|
klao@1056
|
180 |
catch(...) {}
|
klao@1056
|
181 |
if( mes ) return mes;
|
klao@1056
|
182 |
return "lemon::DataFormatError";
|
klao@1056
|
183 |
}
|
alpar@883
|
184 |
};
|
alpar@883
|
185 |
|
klao@1056
|
186 |
|
klao@1056
|
187 |
|
klao@1056
|
188 |
/**************** Macros ****************/
|
klao@1056
|
189 |
|
klao@1056
|
190 |
|
alpar@883
|
191 |
/**
|
klao@1056
|
192 |
* \brief Macro for assertions with customizable message
|
alpar@883
|
193 |
*/
|
klao@1056
|
194 |
|
klao@1056
|
195 |
# define lemon_assert(exp, msg) \
|
klao@1056
|
196 |
if(!(exp)) { \
|
klao@1056
|
197 |
std::cerr << __FILE__ ":" << __LINE__ << ": " << (msg) << std::endl; \
|
klao@1056
|
198 |
abort; \
|
klao@1056
|
199 |
}
|
klao@1056
|
200 |
|
alpar@883
|
201 |
|
alpar@883
|
202 |
/**
|
alpar@883
|
203 |
* \brief Macro for mark not yet implemented features.
|
alpar@883
|
204 |
*
|
alpar@883
|
205 |
* \todo Is this the right place for this? It should be used only in
|
alpar@883
|
206 |
* modules under development.
|
alpar@883
|
207 |
*/
|
alpar@883
|
208 |
|
klao@1056
|
209 |
# define FIXME(msg) lemon_assert(0, "FIXME: " msg)
|
alpar@883
|
210 |
|
alpar@883
|
211 |
}
|
alpar@921
|
212 |
#endif // LEMON_ERROR_H
|