COIN-OR::LEMON - Graph Library

source: lemon-main/lemon/error.h @ 293:47fbc814aa31

Last change on this file since 293:47fbc814aa31 was 280:e7f8647ce760, checked in by Alpar Juttner <alpar@…>, 16 years ago

Remove todo-s and convert them to trac tickets

File size: 9.8 KB
Line 
1/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library.
4 *
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_ERROR_H
20#define LEMON_ERROR_H
21
22/// \ingroup exceptions
23/// \file
24/// \brief Basic exception classes and error handling.
25
26#include <exception>
27#include <string>
28#include <sstream>
29#include <iostream>
30#include <cstdlib>
31#include <memory>
32
33namespace lemon {
34
35  /// \addtogroup exceptions
36  /// @{
37
38  /// \brief Exception safe wrapper class.
39  ///
40  /// Exception safe wrapper class to implement the members of exceptions.
41  template <typename _Type>
42  class ExceptionMember {
43  public:
44    typedef _Type Type;
45
46    ExceptionMember() throw() {
47      try {
48        ptr.reset(new Type());
49      } catch (...) {}
50    }
51
52    ExceptionMember(const Type& type) throw() {
53      try {
54        ptr.reset(new Type());
55        if (ptr.get() == 0) return;
56        *ptr = type;
57      } catch (...) {}
58    }
59
60    ExceptionMember(const ExceptionMember& copy) throw() {
61      try {
62        if (!copy.valid()) return;
63        ptr.reset(new Type());
64        if (ptr.get() == 0) return;
65        *ptr = copy.get();
66      } catch (...) {}
67    }
68
69    ExceptionMember& operator=(const ExceptionMember& copy) throw() {
70      if (ptr.get() == 0) return;
71      try {
72        if (!copy.valid()) return;
73        *ptr = copy.get();
74      } catch (...) {}
75    }
76
77    void set(const Type& type) throw() {
78      if (ptr.get() == 0) return;
79      try {
80        *ptr = type;
81      } catch (...) {}
82    }
83
84    const Type& get() const {
85      return *ptr;
86    }
87
88    bool valid() const throw() {
89      return ptr.get() != 0;
90    }
91
92  private:
93    std::auto_ptr<_Type> ptr;
94  };
95
96  /// Exception-safe convenient error message builder class.
97
98  /// Helper class which provides a convenient ostream-like (operator <<
99  /// based) interface to create a string message. Mostly useful in
100  /// exception classes (therefore the name).
101  class ErrorMessage {
102  protected:
103    ///\e
104
105    mutable std::auto_ptr<std::ostringstream> buf;
106
107    ///\e
108    bool init() throw() {
109      try {
110        buf.reset(new std::ostringstream);
111      }
112      catch(...) {
113        buf.reset();
114      }
115      return buf.get();
116    }
117
118  public:
119
120    ///\e
121    ErrorMessage() throw() { init(); }
122
123    ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
124
125    ///\e
126    ErrorMessage(const char *msg) throw() {
127      init();
128      *this << msg;
129    }
130
131    ///\e
132    ErrorMessage(const std::string &msg) throw() {
133      init();
134      *this << msg;
135    }
136
137    ///\e
138    template <typename T>
139    ErrorMessage& operator<<(const T &t) throw() {
140      if( ! buf.get() ) return *this;
141
142      try {
143        *buf << t;
144      }
145      catch(...) {
146        buf.reset();
147      }
148      return *this;
149    }
150
151    ///\e
152    const char* message() throw() {
153      if( ! buf.get() ) return 0;
154
155      const char* mes = 0;
156      try {
157        mes = buf->str().c_str();
158      }
159      catch(...) {}
160      return mes;
161    }
162
163  };
164
165  /// Generic exception class.
166
167  /// Base class for exceptions used in LEMON.
168  ///
169  class Exception : public std::exception {
170  public:
171    ///\e
172    Exception() {}
173    ///\e
174    virtual ~Exception() throw() {}
175    ///\e
176    virtual const char* what() const throw() {
177      return "lemon::Exception";
178    }
179  };
180
181  /// One of the two main subclasses of \ref Exception.
182
183  /// Logic errors represent problems in the internal logic of a program;
184  /// in theory, these are preventable, and even detectable before the
185  /// program runs (e.g. violations of class invariants).
186  ///
187  /// A typical example for this is \ref UninitializedParameter.
188  class LogicError : public Exception {
189  public:
190    virtual const char* what() const throw() {
191      return "lemon::LogicError";
192    }
193  };
194
195  /// \ref Exception for uninitialized parameters.
196
197  /// This error represents problems in the initialization
198  /// of the parameters of the algorithms.
199  class UninitializedParameter : public LogicError {
200  public:
201    virtual const char* what() const throw() {
202      return "lemon::UninitializedParameter";
203    }
204  };
205
206
207  /// One of the two main subclasses of \ref Exception.
208
209  /// Runtime errors represent problems outside the scope of a program;
210  /// they cannot be easily predicted and can generally only be caught
211  /// as the program executes.
212  class RuntimeError : public Exception {
213  public:
214    virtual const char* what() const throw() {
215      return "lemon::RuntimeError";
216    }
217  };
218
219  ///\e
220  class RangeError : public RuntimeError {
221  public:
222    virtual const char* what() const throw() {
223      return "lemon::RangeError";
224    }
225  };
226
227  ///\e
228  class IoError : public RuntimeError {
229  public:
230    virtual const char* what() const throw() {
231      return "lemon::IoError";
232    }
233  };
234
235  ///\e
236  class DataFormatError : public IoError {
237  protected:
238    ExceptionMember<std::string> _message;
239    ExceptionMember<std::string> _file;
240    int _line;
241
242    mutable ExceptionMember<std::string> _message_holder;
243  public:
244
245    DataFormatError(const DataFormatError &dfe) :
246      IoError(dfe), _message(dfe._message), _file(dfe._file),
247      _line(dfe._line) {}
248
249    ///\e
250    explicit DataFormatError(const char *the_message)
251      : _message(the_message), _line(0) {}
252
253    ///\e
254    DataFormatError(const std::string &file_name, int line_num,
255                    const char *the_message)
256      : _message(the_message), _line(line_num) { file(file_name); }
257
258    ///\e
259    void line(int ln) { _line = ln; }
260    ///\e
261    void message(const std::string& msg) { _message.set(msg); }
262    ///\e
263    void file(const std::string &fl) { _file.set(fl); }
264
265    ///\e
266    int line() const { return _line; }
267    ///\e
268    const char* message() const {
269      if (_message.valid() && !_message.get().empty()) {
270        return _message.get().c_str();
271      } else {
272        return 0;
273      }
274    }
275
276    /// \brief Returns the filename.
277    ///
278    /// Returns \e null if the filename was not specified.
279    const char* file() const {
280      if (_file.valid() && !_file.get().empty()) {
281        return _file.get().c_str();
282      } else {
283        return 0;
284      }
285    }
286
287    ///\e
288    virtual const char* what() const throw() {
289      try {
290        std::ostringstream ostr;
291        ostr << "lemon:DataFormatError" << ": ";
292        if (message()) ostr << message();
293        if( file() || line() != 0 ) {
294          ostr << " (";
295          if( file() ) ostr << "in file '" << file() << "'";
296          if( file() && line() != 0 ) ostr << " ";
297          if( line() != 0 ) ostr << "at line " << line();
298          ostr << ")";
299        }
300        _message_holder.set(ostr.str());
301      }
302      catch (...) {}
303      if( _message_holder.valid()) return _message_holder.get().c_str();
304      return "lemon:DataFormatError";
305    }
306
307    virtual ~DataFormatError() throw() {}
308  };
309
310  ///\e
311  class FileOpenError : public IoError {
312  protected:
313    ExceptionMember<std::string> _file;
314
315    mutable ExceptionMember<std::string> _message_holder;
316  public:
317
318    FileOpenError(const FileOpenError &foe) :
319      IoError(foe), _file(foe._file) {}
320
321    ///\e
322    explicit FileOpenError(const std::string& fl)
323      : _file(fl) {}
324
325
326    ///\e
327    void file(const std::string &fl) { _file.set(fl); }
328
329    /// \brief Returns the filename.
330    ///
331    /// Returns \e null if the filename was not specified.
332    const char* file() const {
333      if (_file.valid() && !_file.get().empty()) {
334        return _file.get().c_str();
335      } else {
336        return 0;
337      }
338    }
339
340    ///\e
341    virtual const char* what() const throw() {
342      try {
343        std::ostringstream ostr;
344        ostr << "lemon::FileOpenError" << ": ";
345        ostr << "Cannot open file - " << file();
346        _message_holder.set(ostr.str());
347      }
348      catch (...) {}
349      if( _message_holder.valid()) return _message_holder.get().c_str();
350      return "lemon::FileOpenError";
351    }
352    virtual ~FileOpenError() throw() {}
353  };
354
355  class IoParameterError : public IoError {
356  protected:
357    ExceptionMember<std::string> _message;
358    ExceptionMember<std::string> _file;
359
360    mutable ExceptionMember<std::string> _message_holder;
361  public:
362
363    IoParameterError(const IoParameterError &ile) :
364      IoError(ile), _message(ile._message), _file(ile._file) {}
365
366    ///\e
367    explicit IoParameterError(const char *the_message)
368      : _message(the_message) {}
369
370    ///\e
371    IoParameterError(const char *file_name, const char *the_message)
372      : _message(the_message), _file(file_name) {}
373
374     ///\e
375    void message(const std::string& msg) { _message.set(msg); }
376    ///\e
377    void file(const std::string &fl) { _file.set(fl); }
378
379     ///\e
380    const char* message() const {
381      if (_message.valid()) {
382        return _message.get().c_str();
383      } else {
384        return 0;
385      }
386    }
387
388    /// \brief Returns the filename.
389    ///
390    /// Returns \c 0 if the filename was not specified.
391    const char* file() const {
392      if (_file.valid()) {
393        return _file.get().c_str();
394      } else {
395        return 0;
396      }
397    }
398
399    ///\e
400    virtual const char* what() const throw() {
401      try {
402        std::ostringstream ostr;
403        if (message()) ostr << message();
404        if (file()) ostr << "(when reading file '" << file() << "')";
405        _message_holder.set(ostr.str());
406      }
407      catch (...) {}
408      if( _message_holder.valid() ) return _message_holder.get().c_str();
409      return "lemon:IoParameterError";
410    }
411    virtual ~IoParameterError() throw() {}
412  };
413
414  /// @}
415
416}
417
418#endif // LEMON_ERROR_H
Note: See TracBrowser for help on using the repository browser.