COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/error.h

    r280 r291  
    3636  /// @{
    3737
    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 
     38  /// \brief Generic exception class.
     39  ///
    16740  /// Base class for exceptions used in LEMON.
    16841  ///
    16942  class Exception : public std::exception {
    17043  public:
    171     ///\e
    172     Exception() {}
    173     ///\e
     44    ///Constructor
     45    Exception() throw() {}
     46    ///Virtual destructor
    17447    virtual ~Exception() throw() {}
    175     ///\e
     48    ///A short description of the exception
    17649    virtual const char* what() const throw() {
    17750      return "lemon::Exception";
     
    17952  };
    18053
    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 {
     54  /// \brief Input-Output error
     55  ///
     56  /// This exception is thrown when a file operation cannot be
     57  /// succeeded.
     58  class IoError : public Exception {
     59  protected:
     60    std::string _message;
     61    std::string _file;
     62
     63    mutable std::string _what;
    18964  public:
     65
     66    /// Copy constructor
     67    IoError(const IoError &error) throw() : Exception() {
     68      message(error._message);
     69      file(error._file);
     70    }
     71
     72    /// Constructor
     73    explicit IoError(const char *message) throw() {
     74      IoError::message(message);
     75    }
     76
     77    /// Constructor
     78    explicit IoError(const std::string &message) throw() {
     79      IoError::message(message);
     80    }
     81
     82    /// Constructor
     83    explicit IoError(const char *message,
     84                     const std::string &file) throw() {
     85      IoError::message(message);
     86      IoError::file(file);
     87    }
     88
     89    /// Constructor
     90    explicit IoError(const std::string &message,
     91                     const std::string &file) throw() {
     92      IoError::message(message);
     93      IoError::file(file);
     94    }
     95
     96    /// Virtual destructor
     97    virtual ~IoError() throw() {}
     98
     99    /// Set the error message
     100    void message(const char *message) throw() {
     101      try {
     102        _message = message;
     103      } catch (...) {}
     104    }
     105
     106    /// Set the error message
     107    void message(const std::string& message) throw() {
     108      try {
     109        _message = message;
     110      } catch (...) {}
     111    }
     112
     113    /// Set the file name
     114    void file(const std::string &file) throw() {
     115      try {
     116        _file = file;
     117      } catch (...) {}
     118    }
     119
     120    /// Returns the error message
     121    const std::string& message() const throw() {
     122      return _message;
     123    }
     124
     125    /// \brief Returns the filename
     126    ///
     127    /// Returns the filename or an empty string if it was not specified.
     128    const std::string& file() const throw() {
     129      return _file;
     130    }
     131
     132    /// \brief Returns a short error message
     133    ///
     134    /// Returns a short error message which contains the message and the
     135    /// file name.
    190136    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 << ")";
     137      try {
     138        _what.clear();
     139        std::ostringstream oss;
     140        oss << "lemon:IoError" << ": ";
     141        oss << _message;
     142        if (!_file.empty()) {
     143          oss << " ('" << _file << "')";
    299144        }
    300         _message_holder.set(ostr.str());
     145        _what = oss.str();
    301146      }
    302147      catch (...) {}
    303       if( _message_holder.valid()) return _message_holder.get().c_str();
    304       return "lemon:DataFormatError";
    305     }
    306 
    307     virtual ~DataFormatError() throw() {}
     148      if (!_what.empty()) return _what.c_str();
     149      else return "lemon:IoError";
     150    }
     151
    308152  };
    309153
    310   ///\e
    311   class FileOpenError : public IoError {
     154  /// \brief Format error
     155  ///
     156  /// This exception is thrown when an input file has wrong
     157  /// format or a data representation is not legal.
     158  class FormatError : public Exception {
    312159  protected:
    313     ExceptionMember<std::string> _file;
    314 
    315     mutable ExceptionMember<std::string> _message_holder;
     160    std::string _message;
     161    std::string _file;
     162    int _line;
     163
     164    mutable std::string _what;
    316165  public:
    317166
    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
     167    /// Copy constructor
     168    FormatError(const FormatError &error) throw() : Exception() {
     169      message(error._message);
     170      file(error._file);
     171      line(error._line);
     172    }
     173
     174    /// Constructor
     175    explicit FormatError(const char *message) throw() {
     176      FormatError::message(message);
     177      _line = 0;
     178    }
     179
     180    /// Constructor
     181    explicit FormatError(const std::string &message) throw() {
     182      FormatError::message(message);
     183      _line = 0;
     184    }
     185
     186    /// Constructor
     187    explicit FormatError(const char *message,
     188                         const std::string &file, int line = 0) throw() {
     189      FormatError::message(message);
     190      FormatError::file(file);
     191      FormatError::line(line);
     192    }
     193
     194    /// Constructor
     195    explicit FormatError(const std::string &message,
     196                         const std::string &file, int line = 0) throw() {
     197      FormatError::message(message);
     198      FormatError::file(file);
     199      FormatError::line(line);
     200    }
     201
     202    /// Virtual destructor
     203    virtual ~FormatError() throw() {}
     204
     205    /// Set the line number
     206    void line(int line) throw() { _line = line; }
     207
     208    /// Set the error message
     209    void message(const char *message) throw() {
     210      try {
     211        _message = message;
     212      } catch (...) {}
     213    }
     214
     215    /// Set the error message
     216    void message(const std::string& message) throw() {
     217      try {
     218        _message = message;
     219      } catch (...) {}
     220    }
     221
     222    /// Set the file name
     223    void file(const std::string &file) throw() {
     224      try {
     225        _file = file;
     226      } catch (...) {}
     227    }
     228
     229    /// \brief Returns the line number
     230    ///
     231    /// Returns the line number or zero if it was not specified.
     232    int line() const throw() { return _line; }
     233
     234    /// Returns the error message
     235    const std::string& message() const throw() {
     236      return _message;
     237    }
     238
     239    /// \brief Returns the filename
     240    ///
     241    /// Returns the filename or an empty string if it was not specified.
     242    const std::string& file() const throw() {
     243      return _file;
     244    }
     245
     246    /// \brief Returns a short error message
     247    ///
     248    /// Returns a short error message which contains the message, the
     249    /// file name and the line number.
    341250    virtual const char* what() const throw() {
    342251      try {
    343         std::ostringstream ostr;
    344         ostr << "lemon::FileOpenError" << ": ";
    345         ostr << "Cannot open file - " << file();
    346         _message_holder.set(ostr.str());
     252        _what.clear();
     253        std::ostringstream oss;
     254        oss << "lemon:FormatError" << ": ";
     255        oss << _message;
     256        if (!_file.empty() || _line != 0) {
     257          oss << " (";
     258          if (!_file.empty()) oss << "in file '" << _file << "'";
     259          if (!_file.empty() && _line != 0) oss << " ";
     260          if (_line != 0) oss << "at line " << _line;
     261          oss << ")";
     262        }
     263        _what = oss.str();
    347264      }
    348265      catch (...) {}
    349       if( _message_holder.valid()) return _message_holder.get().c_str();
    350       return "lemon::FileOpenError";
    351     }
    352     virtual ~FileOpenError() throw() {}
     266      if (!_what.empty()) return _what.c_str();
     267      else return "lemon:FormatError";
     268    }
     269
    353270  };
    354271
    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 
    414272  /// @}
    415273
Note: See TracChangeset for help on using the changeset viewer.