src/lemon/error.h
changeset 1162 2f51fccbc261
parent 1151 b217fc69f913
child 1164 80bb73097736
equal deleted inserted replaced
3:32ca28045568 4:009cc16c512d
     1 /* -*- C++ -*-
     1 /* -*- C++ -*-
       
     2  *
     2  * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
     3  * src/lemon/error.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
       
     7  * EGRES).
     6  *
     8  *
     7  * Permission to use, modify and distribute this software is granted
     9  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
    10  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    11  * precise terms see the accompanying LICENSE file.
    10  *
    12  *
    24 #include <exception>
    26 #include <exception>
    25 #include <string>
    27 #include <string>
    26 #include <sstream>
    28 #include <sstream>
    27 #include <iostream>
    29 #include <iostream>
    28 #include <cstdlib>
    30 #include <cstdlib>
    29 
    31 #include <memory>
    30 #include <boost/shared_ptr.hpp>
       
    31 
    32 
    32 namespace lemon {
    33 namespace lemon {
    33 
    34 
    34 /// \addtogroup exceptions
    35 /// \addtogroup exceptions
    35 /// @{
    36 /// @{
    40   /// based) interface to create a string message. Mostly useful in
    41   /// based) interface to create a string message. Mostly useful in
    41   /// exception classes (therefore the name).
    42   /// exception classes (therefore the name).
    42   class ErrorMessage {
    43   class ErrorMessage {
    43   protected:
    44   protected:
    44     ///\e 
    45     ///\e 
    45     boost::shared_ptr<std::ostringstream> buf;
    46     ///\todo The good solution is boost:shared_ptr...
       
    47     mutable
       
    48     std::auto_ptr<std::ostringstream> buf;
    46     
    49     
    47     ///\e 
    50     ///\e 
    48     bool init() throw() {
    51     bool init() throw() {
    49       try {
    52       try {
    50 	buf.reset(new std::ostringstream);
    53 	buf.reset(new std::ostringstream);
    51       }
    54       }
    52       catch(...) {
    55       catch(...) {
    53 	buf.reset();
    56 	buf.reset();
    54       }
    57       }
    55       return buf;
    58       return buf.get();
    56     }
    59     }
    57 
    60 
    58   public:
    61   public:
    59 
    62 
    60     ///\e 
    63     ///\e 
    61     ErrorMessage() throw() { init(); }
    64     ErrorMessage() throw() { init(); }
       
    65 
       
    66     ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
    62 
    67 
    63     ///\e 
    68     ///\e 
    64     ErrorMessage(const char *message) throw() {
    69     ErrorMessage(const char *message) throw() {
    65       init();
    70       init();
    66       *this << message;
    71       *this << message;
    73     }
    78     }
    74 
    79 
    75     ///\e 
    80     ///\e 
    76     template <typename T>
    81     template <typename T>
    77     ErrorMessage& operator<<(const T &t) throw() {
    82     ErrorMessage& operator<<(const T &t) throw() {
    78       if( !buf ) return *this;
    83       if( ! buf.get() ) return *this;
    79 
    84 
    80       try {
    85       try {
    81 	*buf << t;
    86 	*buf << t;
    82       }
    87       }
    83       catch(...) {
    88       catch(...) {
    85       }
    90       }
    86     }
    91     }
    87 
    92 
    88     ///\e 
    93     ///\e 
    89     const char* message() throw() {
    94     const char* message() throw() {
    90       if( !buf ) return 0;
    95       if( ! buf.get() ) return 0;
    91 
    96 
    92       const char* mes = 0;
    97       const char* mes = 0;
    93       try {
    98       try {
    94 	mes = buf->str().c_str();
    99 	mes = buf->str().c_str();
    95       }
   100       }
   185   ///\e 
   190   ///\e 
   186   class DataFormatError : public IOError {
   191   class DataFormatError : public IOError {
   187   protected:
   192   protected:
   188     const char *_message;
   193     const char *_message;
   189     int _line;
   194     int _line;
   190     boost::shared_ptr<std::string> _file;
   195 
   191 
   196     ///\todo Much better solution is boost::shared_ptr
   192   public:
   197     mutable
       
   198     std::auto_ptr<std::string> _file;
       
   199 
       
   200   public:
       
   201 
       
   202     DataFormatError(const DataFormatError &dfe) : 
       
   203       IOError(dfe), _message(dfe._message), _line(dfe._line),
       
   204       _file(dfe._file) {}
       
   205 
   193     ///\e 
   206     ///\e 
   194     explicit DataFormatError(const char *the_message)
   207     explicit DataFormatError(const char *the_message)
   195       : _message(the_message), _line(0) {}
   208       : _message(the_message), _line(0) {}
   196     ///\e 
   209     ///\e 
   197     DataFormatError(const std::string &file_name, int line_num,
   210     DataFormatError(const std::string &file_name, int line_num,
   220 
   233 
   221     /// \brief Returns the filename.
   234     /// \brief Returns the filename.
   222     ///
   235     ///
   223     /// Returns \e "(unknown)" if the filename was not specified.
   236     /// Returns \e "(unknown)" if the filename was not specified.
   224     const char* file() const {
   237     const char* file() const {
   225       if( _file )
   238       if( _file.get() )
   226 	return _file->c_str();
   239 	return _file->c_str();
   227       else
   240       else
   228 	return "(unknown)";
   241 	return "(unknown)";
   229     }
   242     }
   230 
   243 
   232     virtual const char* what() const throw() {
   245     virtual const char* what() const throw() {
   233       const char *mes = 0;
   246       const char *mes = 0;
   234       try {
   247       try {
   235 	std::ostringstream ostr;
   248 	std::ostringstream ostr;
   236 	ostr << _message;
   249 	ostr << _message;
   237 	if( _file || _line ) {
   250 	if( _file.get() || _line ) {
   238 	  ostr << " (";
   251 	  ostr << " (";
   239 	  if( _file ) ostr << "in file '" << *_file << "'";
   252 	  if( _file.get() ) ostr << "in file '" << *_file << "'";
   240 	  if( _file && _line ) ostr << " ";
   253 	  if( _file.get() && _line ) ostr << " ";
   241 	  if( _line ) ostr << "at line " << _line;
   254 	  if( _line ) ostr << "at line " << _line;
   242 	  ostr << ")";
   255 	  ostr << ")";
   243 	}
   256 	}
   244 	mes = ostr.str().c_str();
   257 	mes = ostr.str().c_str();
   245       }
   258       }