COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/klao/error.h @ 1068:e0b0dcee5e17

Last change on this file since 1068:e0b0dcee5e17 was 1068:e0b0dcee5e17, checked in by Mihaly Barasz, 17 years ago
File size: 7.6 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
10 *
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_ERROR_H
18#define LEMON_ERROR_H
19
20//! \ingroup misc
21//! \file
22//! \brief Basic exception classes and error handling.
23
24#include <exception>
25#include <string>
26#include <sstream>
27#include <iostream>
28#include <cstdlib>
29
30#include <boost/shared_ptr.hpp>
31
32namespace lemon {
33
34  /// Exception-safe convenient "error message" class.
35
36  /// Helper class which provides a convenient ostream-like (operator <<
37  /// based) interface to create a string message. Mostly useful in
38  /// exception classes (therefore the name).
39  class ErrorMessage {
40  protected:
41    ///\e
42    boost::shared_ptr<std::ostringstream> buf;
43   
44    ///\e
45    bool init() throw() {
46      try {
47        buf.reset(new std::ostringstream);
48      }
49      catch(...) {
50        buf.reset();
51      }
52      return buf;
53    }
54
55  public:
56
57    ///\e
58    ErrorMessage() throw() { init(); }
59
60    ///\e
61    ErrorMessage(const char *message) throw() {
62      init();
63      *this << message;
64    }
65
66    ///\e
67    ErrorMessage(const std::string &message) throw() {
68      init();
69      *this << message;
70    }
71
72    ///\e
73    template <typename T>
74    ErrorMessage& operator<<(const T &t) throw() {
75      if( !buf ) return *this;
76
77      try {
78        *buf << t;
79      }
80      catch(...) {
81        buf.reset();
82      }
83    }
84
85    ///\e
86    const char* message() throw() {
87      if( !buf ) return 0;
88
89      const char* mes = 0;
90      try {
91        mes = buf->str().c_str();
92      }
93      catch(...) {}
94      return mes;
95    }
96   
97  };
98
99  /**
100   * \brief Generic exception class.
101   *
102   * Base class for exceptions used in LEMON.
103   */
104  class Exception : public std::exception {
105  protected:
106    ///\e
107    const char *message;
108
109  public:
110    ///\e
111    Exception() throw() : message(0) {}
112    ///\e
113    explicit Exception(const char *msg) throw()
114      : message(msg) {}
115    ///\e
116    virtual ~Exception() throw() {}
117   
118    ///\e
119    virtual const char* what() const throw() {
120      if( message ) return message;
121      return "lemon::Exception";
122    }
123  };
124
125  ///\e
126  class LogicError : public Exception {
127  public:
128    ///\e
129    explicit LogicError() {}
130    ///\e
131    explicit LogicError(const char *s)
132      : Exception(s) {}
133  };
134
135  ///\e
136  class RuntimeError : public Exception {
137  public:
138    ///\e
139    explicit RuntimeError() {}
140    ///\e
141    explicit RuntimeError(const char *s)
142      : Exception(s) {}
143  };
144
145  ///\e
146  class RangeError : public RuntimeError {
147  public:
148    ///\e
149    explicit RangeError(const char *s)
150      : RuntimeError(s) {}
151  };
152
153  ///\e
154  class IOError : public RuntimeError {
155  public:
156    ///\e
157    explicit IOError(const char *s)
158      : RuntimeError(s) {}
159  };
160
161  ///\e
162  class DataFormatError : public IOError {
163  protected:
164    int line;
165    boost::shared_ptr<std::string> file;
166
167  public:
168    ///\e
169    explicit DataFormatError(const char *message)
170      : IOError(message), line(0) {}
171    ///\e
172    DataFormatError(const std::string &file_name, int line_num,
173                    const char *message)
174      : IOError(message), line(line_num) { set_file(file_name); }
175
176    ///\e
177    void set_line(int line_num) { line=line_num; }
178    ///\e
179    void set_file(const std::string &file_name) {
180      try {
181        file.reset(new std::string);
182        *file = file_name;
183      }
184      catch(...) {
185        file.reset();
186      }
187    }
188
189    ///\e
190    int get_line() const { return line; }
191
192    /// \brief Returns the filename.
193    ///
194    /// Returns \e "(unknown)" if the filename was not specified.
195    const char* get_file() const {
196      if( file )
197        return file->c_str();
198      else
199        return "(unknown)";
200    }
201
202    ///\e
203    virtual const char* what() const throw() {
204      const char *mes = 0;
205      try {
206        std::ostringstream ostr;
207        ostr << IOError::what();
208        if( file || line ) {
209          ostr << " (";
210          if( file ) ostr << "in file '" << *file << "'";
211          if( file && line ) ostr << " ";
212          if( line ) ostr << "at line " << line;
213          ostr << ")";
214        }
215        mes = ostr.str().c_str();
216      }
217      catch(...) {}
218      if( mes ) return mes;
219      return "lemon::DataFormatError";
220    }
221
222    virtual ~DataFormatError() throw() {}
223  };
224
225
226  ///\e
227  class AssertionFailedError : public LogicError {
228  protected:
229    const char *assertion;
230    const char *file;
231    int line;
232    const char *function;
233    const char *message;
234  public:
235    ///\e
236    AssertionFailedError(const char *_file, int _line, const char *func,
237                         const char *msg, const char *_assertion = 0) :
238      assertion(_assertion), file(_file), line(_line), function(func),
239      message(msg) {}
240
241    ///\e
242    const char* get_assertion() const { return assertion; }
243    ///\e
244    const char* get_message() const { return message; }
245    ///\e
246    const char* get_file() const { return file; }
247    ///\e
248    const char* get_function() const { return function; }
249    ///\e
250    int get_line() const { return line; }
251
252
253    virtual const char* what() const throw() {
254      const char *mes = 0;
255      try {
256        std::ostringstream ostr;
257        ostr << file << ":" << line << ": ";
258        if( function )
259          ostr << function << ": ";
260        ostr << message;
261        if( assertion )
262          ostr << " (assertion '" << assertion << "' failed)";
263        mes = ostr.str().c_str();
264      }
265      catch(...) {}
266      if( mes ) return mes;
267      return "lemon::AssertionFailedError";
268    }
269
270    virtual ~AssertionFailedError() throw() {}
271  };
272
273
274  /****************  Macros  ****************/
275
276
277  inline
278  void assert_fail(const char *file, int line, const char *func,
279                   const char *message, const char *assertion = 0,
280                   bool do_abort=true)
281  {
282    using namespace std;
283    cerr << file << ":" << line << ": ";
284    if( func )
285      cerr << func << ": ";
286    cerr << message;
287    if( assertion )
288      cerr << " (assertion '" << assertion << "' failed)";
289    cerr << endl;
290    if(do_abort)
291      abort();
292  }
293
294  inline
295  void assert_fail_throw(const char *file, int line, const char *func,
296                   const char *message, const char *assertion = 0,
297                   bool = true)
298  {
299    throw AssertionFailedError(file, line, func, message, assertion);
300  }
301
302
303}
304#endif // LEMON_ERROR_H
305
306#undef LEMON_ASSERT
307#undef LEMON_FIXME
308
309#ifndef LEMON_ASSERT_ABORT
310#  define LEMON_ASSERT_ABORT 1
311#endif
312
313#ifndef LEMON_ASSERT_HANDLER
314#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail
315#endif
316
317#if defined(NDEBUG) || defined(LEMON_DISABLE_ASSERTS)
318
319#  define LEMON_ASSERT(exp, msg)  (static_cast<void> (0))
320
321#else
322
323/**
324 * \brief Macro for assertions with customizable message
325 *
326 * \todo __PRETTY_FUNCTION__ should be replaced by something
327 * compiler-independant, like BOOST_CURRENT_FUNCTION
328 */
329
330#  define LEMON_ASSERT(exp, msg)                 \
331     (static_cast<void> (!!(exp) ? 0 : (         \
332       LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
333                            __PRETTY_FUNCTION__, \
334                            (msg), #exp, LEMON_ASSERT_ABORT), 0)))
335
336# endif // NDEBUG
337
338/**
339 * \brief Macro for mark not yet implemented features.
340 *
341 * \todo Is this the right place for this? It should be used only in
342 * modules under development.
343 *
344 * \todo __PRETTY_FUNCTION__ should be replaced by something
345 * compiler-independant, like BOOST_CURRENT_FUNCTION
346 */
347
348# define LEMON_FIXME(msg) \
349    (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
350                          "FIXME: " msg))
Note: See TracBrowser for help on using the repository browser.