1.1 --- a/lemon/Makefile.am Mon Feb 04 13:32:36 2008 +0100
1.2 +++ b/lemon/Makefile.am Thu Feb 07 11:52:16 2008 +0000
1.3 @@ -16,9 +16,10 @@
1.4
1.5 lemon_HEADERS += \
1.6 lemon/dim2.h \
1.7 + lemon/error.h \
1.8 + lemon/list_graph.h \
1.9 lemon/maps.h \
1.10 lemon/random.h \
1.11 - lemon/list_graph.h \
1.12 lemon/tolerance.h
1.13
1.14 bits_HEADERS += \
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/lemon/error.h Thu Feb 07 11:52:16 2008 +0000
2.3 @@ -0,0 +1,675 @@
2.4 +/* -*- C++ -*-
2.5 + *
2.6 + * This file is a part of LEMON, a generic C++ optimization library
2.7 + *
2.8 + * Copyright (C) 2003-2008
2.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
2.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
2.11 + *
2.12 + * Permission to use, modify and distribute this software is granted
2.13 + * provided that this copyright notice appears in all copies. For
2.14 + * precise terms see the accompanying LICENSE file.
2.15 + *
2.16 + * This software is provided "AS IS" with no warranty of any kind,
2.17 + * express or implied, and with no claim as to its suitability for any
2.18 + * purpose.
2.19 + *
2.20 + */
2.21 +
2.22 +#ifndef LEMON_ERROR_H
2.23 +#define LEMON_ERROR_H
2.24 +
2.25 +/// \ingroup exceptions
2.26 +/// \file
2.27 +/// \brief Basic exception classes and error handling.
2.28 +
2.29 +#include <exception>
2.30 +#include <string>
2.31 +#include <sstream>
2.32 +#include <iostream>
2.33 +#include <cstdlib>
2.34 +#include <memory>
2.35 +
2.36 +namespace lemon {
2.37 +
2.38 + /// \addtogroup exceptions
2.39 + /// @{
2.40 +
2.41 + /// \brief Exception safe wrapper class.
2.42 + ///
2.43 + /// Exception safe wrapper class to implement the members of exceptions.
2.44 + template <typename _Type>
2.45 + class ExceptionMember {
2.46 + public:
2.47 + typedef _Type Type;
2.48 +
2.49 + ExceptionMember() throw() {
2.50 + try {
2.51 + ptr.reset(new Type());
2.52 + } catch (...) {}
2.53 + }
2.54 +
2.55 + ExceptionMember(const Type& type) throw() {
2.56 + try {
2.57 + ptr.reset(new Type());
2.58 + if (ptr.get() == 0) return;
2.59 + *ptr = type;
2.60 + } catch (...) {}
2.61 + }
2.62 +
2.63 + ExceptionMember(const ExceptionMember& copy) throw() {
2.64 + try {
2.65 + if (!copy.valid()) return;
2.66 + ptr.reset(new Type());
2.67 + if (ptr.get() == 0) return;
2.68 + *ptr = copy.get();
2.69 + } catch (...) {}
2.70 + }
2.71 +
2.72 + ExceptionMember& operator=(const ExceptionMember& copy) throw() {
2.73 + if (ptr.get() == 0) return;
2.74 + try {
2.75 + if (!copy.valid()) return;
2.76 + *ptr = copy.get();
2.77 + } catch (...) {}
2.78 + }
2.79 +
2.80 + void set(const Type& type) throw() {
2.81 + if (ptr.get() == 0) return;
2.82 + try {
2.83 + *ptr = type;
2.84 + } catch (...) {}
2.85 + }
2.86 +
2.87 + const Type& get() const {
2.88 + return *ptr;
2.89 + }
2.90 +
2.91 + bool valid() const throw() {
2.92 + return ptr.get() != 0;
2.93 + }
2.94 +
2.95 + private:
2.96 + std::auto_ptr<_Type> ptr;
2.97 + };
2.98 +
2.99 + /// Exception-safe convenient "error message" class.
2.100 +
2.101 + /// Helper class which provides a convenient ostream-like (operator <<
2.102 + /// based) interface to create a string message. Mostly useful in
2.103 + /// exception classes (therefore the name).
2.104 + class ErrorMessage {
2.105 + protected:
2.106 + ///\e
2.107 +
2.108 + ///\todo The good solution is boost::shared_ptr...
2.109 + ///
2.110 + mutable std::auto_ptr<std::ostringstream> buf;
2.111 +
2.112 + ///\e
2.113 + bool init() throw() {
2.114 + try {
2.115 + buf.reset(new std::ostringstream);
2.116 + }
2.117 + catch(...) {
2.118 + buf.reset();
2.119 + }
2.120 + return buf.get();
2.121 + }
2.122 +
2.123 + public:
2.124 +
2.125 + ///\e
2.126 + ErrorMessage() throw() { init(); }
2.127 +
2.128 + ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
2.129 +
2.130 + ///\e
2.131 + ErrorMessage(const char *msg) throw() {
2.132 + init();
2.133 + *this << msg;
2.134 + }
2.135 +
2.136 + ///\e
2.137 + ErrorMessage(const std::string &msg) throw() {
2.138 + init();
2.139 + *this << msg;
2.140 + }
2.141 +
2.142 + ///\e
2.143 + template <typename T>
2.144 + ErrorMessage& operator<<(const T &t) throw() {
2.145 + if( ! buf.get() ) return *this;
2.146 +
2.147 + try {
2.148 + *buf << t;
2.149 + }
2.150 + catch(...) {
2.151 + buf.reset();
2.152 + }
2.153 + return *this;
2.154 + }
2.155 +
2.156 + ///\e
2.157 + const char* message() throw() {
2.158 + if( ! buf.get() ) return 0;
2.159 +
2.160 + const char* mes = 0;
2.161 + try {
2.162 + mes = buf->str().c_str();
2.163 + }
2.164 + catch(...) {}
2.165 + return mes;
2.166 + }
2.167 +
2.168 + };
2.169 +
2.170 + /// Generic exception class.
2.171 +
2.172 + /// Base class for exceptions used in LEMON.
2.173 + ///
2.174 + class Exception : public std::exception {
2.175 + public:
2.176 + ///\e
2.177 + Exception() {}
2.178 + ///\e
2.179 + virtual ~Exception() throw() {}
2.180 + ///\e
2.181 + virtual const char* what() const throw() {
2.182 + return "lemon::Exception";
2.183 + }
2.184 + };
2.185 +
2.186 + /// One of the two main subclasses of \ref Exception.
2.187 +
2.188 + /// Logic errors represent problems in the internal logic of a program;
2.189 + /// in theory, these are preventable, and even detectable before the
2.190 + /// program runs (e.g. violations of class invariants).
2.191 + ///
2.192 + /// A typical example for this is \ref UninitializedParameter.
2.193 + class LogicError : public Exception {
2.194 + public:
2.195 + virtual const char* what() const throw() {
2.196 + return "lemon::LogicError";
2.197 + }
2.198 + };
2.199 +
2.200 + /// \ref Exception for uninitialized parameters.
2.201 +
2.202 + /// This error represents problems in the initialization
2.203 + /// of the parameters of the algorithms.
2.204 + class UninitializedParameter : public LogicError {
2.205 + public:
2.206 + virtual const char* what() const throw() {
2.207 + return "lemon::UninitializedParameter";
2.208 + }
2.209 + };
2.210 +
2.211 +
2.212 + /// One of the two main subclasses of \ref Exception.
2.213 +
2.214 + /// Runtime errors represent problems outside the scope of a program;
2.215 + /// they cannot be easily predicted and can generally only be caught
2.216 + /// as the program executes.
2.217 + class RuntimeError : public Exception {
2.218 + public:
2.219 + virtual const char* what() const throw() {
2.220 + return "lemon::RuntimeError";
2.221 + }
2.222 + };
2.223 +
2.224 + ///\e
2.225 + class RangeError : public RuntimeError {
2.226 + public:
2.227 + virtual const char* what() const throw() {
2.228 + return "lemon::RangeError";
2.229 + }
2.230 + };
2.231 +
2.232 + ///\e
2.233 + class IoError : public RuntimeError {
2.234 + public:
2.235 + virtual const char* what() const throw() {
2.236 + return "lemon::IoError";
2.237 + }
2.238 + };
2.239 +
2.240 + ///\e
2.241 + class DataFormatError : public IoError {
2.242 + protected:
2.243 + ExceptionMember<std::string> _message;
2.244 + ExceptionMember<std::string> _file;
2.245 + int _line;
2.246 +
2.247 + mutable ExceptionMember<std::string> _message_holder;
2.248 + public:
2.249 +
2.250 + DataFormatError(const DataFormatError &dfe) :
2.251 + IoError(dfe), _message(dfe._message), _file(dfe._file),
2.252 + _line(dfe._line) {}
2.253 +
2.254 + ///\e
2.255 + explicit DataFormatError(const char *the_message)
2.256 + : _message(the_message), _line(0) {}
2.257 +
2.258 + ///\e
2.259 + DataFormatError(const std::string &file_name, int line_num,
2.260 + const char *the_message)
2.261 + : _message(the_message), _line(line_num) { file(file_name); }
2.262 +
2.263 + ///\e
2.264 + void line(int ln) { _line = ln; }
2.265 + ///\e
2.266 + void message(const std::string& msg) { _message.set(msg); }
2.267 + ///\e
2.268 + void file(const std::string &fl) { _file.set(fl); }
2.269 +
2.270 + ///\e
2.271 + int line() const { return _line; }
2.272 + ///\e
2.273 + const char* message() const {
2.274 + if (_message.valid() && !_message.get().empty()) {
2.275 + return _message.get().c_str();
2.276 + } else {
2.277 + return 0;
2.278 + }
2.279 + }
2.280 +
2.281 + /// \brief Returns the filename.
2.282 + ///
2.283 + /// Returns \e null if the filename was not specified.
2.284 + const char* file() const {
2.285 + if (_file.valid() && !_file.get().empty()) {
2.286 + return _file.get().c_str();
2.287 + } else {
2.288 + return 0;
2.289 + }
2.290 + }
2.291 +
2.292 + ///\e
2.293 + virtual const char* what() const throw() {
2.294 + try {
2.295 + std::ostringstream ostr;
2.296 + ostr << "lemon:DataFormatError" << ": ";
2.297 + if (message()) ostr << message();
2.298 + if( file() || line() != 0 ) {
2.299 + ostr << " (";
2.300 + if( file() ) ostr << "in file '" << file() << "'";
2.301 + if( file() && line() != 0 ) ostr << " ";
2.302 + if( line() != 0 ) ostr << "at line " << line();
2.303 + ostr << ")";
2.304 + }
2.305 + _message_holder.set(ostr.str());
2.306 + }
2.307 + catch (...) {}
2.308 + if( _message_holder.valid()) return _message_holder.get().c_str();
2.309 + return "lemon:DataFormatError";
2.310 + }
2.311 +
2.312 + virtual ~DataFormatError() throw() {}
2.313 + };
2.314 +
2.315 + ///\e
2.316 + class FileOpenError : public IoError {
2.317 + protected:
2.318 + ExceptionMember<std::string> _file;
2.319 +
2.320 + mutable ExceptionMember<std::string> _message_holder;
2.321 + public:
2.322 +
2.323 + FileOpenError(const FileOpenError &foe) :
2.324 + IoError(foe), _file(foe._file) {}
2.325 +
2.326 + ///\e
2.327 + explicit FileOpenError(const std::string& fl)
2.328 + : _file(fl) {}
2.329 +
2.330 +
2.331 + ///\e
2.332 + void file(const std::string &fl) { _file.set(fl); }
2.333 +
2.334 + /// \brief Returns the filename.
2.335 + ///
2.336 + /// Returns \e null if the filename was not specified.
2.337 + const char* file() const {
2.338 + if (_file.valid() && !_file.get().empty()) {
2.339 + return _file.get().c_str();
2.340 + } else {
2.341 + return 0;
2.342 + }
2.343 + }
2.344 +
2.345 + ///\e
2.346 + virtual const char* what() const throw() {
2.347 + try {
2.348 + std::ostringstream ostr;
2.349 + ostr << "lemon::FileOpenError" << ": ";
2.350 + ostr << "Cannot open file - " << file();
2.351 + _message_holder.set(ostr.str());
2.352 + }
2.353 + catch (...) {}
2.354 + if( _message_holder.valid()) return _message_holder.get().c_str();
2.355 + return "lemon::FileOpenError";
2.356 + }
2.357 + virtual ~FileOpenError() throw() {}
2.358 + };
2.359 +
2.360 + class IoParameterError : public IoError {
2.361 + protected:
2.362 + ExceptionMember<std::string> _message;
2.363 + ExceptionMember<std::string> _file;
2.364 +
2.365 + mutable ExceptionMember<std::string> _message_holder;
2.366 + public:
2.367 +
2.368 + IoParameterError(const IoParameterError &ile) :
2.369 + IoError(ile), _message(ile._message), _file(ile._file) {}
2.370 +
2.371 + ///\e
2.372 + explicit IoParameterError(const char *the_message)
2.373 + : _message(the_message) {}
2.374 +
2.375 + ///\e
2.376 + IoParameterError(const char *file_name, const char *the_message)
2.377 + : _message(the_message), _file(file_name) {}
2.378 +
2.379 + ///\e
2.380 + void message(const std::string& msg) { _message.set(msg); }
2.381 + ///\e
2.382 + void file(const std::string &fl) { _file.set(fl); }
2.383 +
2.384 + ///\e
2.385 + const char* message() const {
2.386 + if (_message.valid()) {
2.387 + return _message.get().c_str();
2.388 + } else {
2.389 + return 0;
2.390 + }
2.391 + }
2.392 +
2.393 + /// \brief Returns the filename.
2.394 + ///
2.395 + /// Returns \c 0 if the filename was not specified.
2.396 + const char* file() const {
2.397 + if (_file.valid()) {
2.398 + return _file.get().c_str();
2.399 + } else {
2.400 + return 0;
2.401 + }
2.402 + }
2.403 +
2.404 + ///\e
2.405 + virtual const char* what() const throw() {
2.406 + try {
2.407 + std::ostringstream ostr;
2.408 + if (message()) ostr << message();
2.409 + if (file()) ostr << "(when reading file '" << file() << "')";
2.410 + _message_holder.set(ostr.str());
2.411 + }
2.412 + catch (...) {}
2.413 + if( _message_holder.valid() ) return _message_holder.get().c_str();
2.414 + return "lemon:IoParameterError";
2.415 + }
2.416 + virtual ~IoParameterError() throw() {}
2.417 + };
2.418 +
2.419 +
2.420 + ///\e
2.421 + class AssertionFailedError : public LogicError {
2.422 + protected:
2.423 + const char *assertion;
2.424 + const char *file;
2.425 + int line;
2.426 + const char *function;
2.427 + const char *message;
2.428 +
2.429 + mutable ExceptionMember<std::string> _message_holder;
2.430 + public:
2.431 + ///\e
2.432 + AssertionFailedError(const char *_file, int _line, const char *func,
2.433 + const char *msg, const char *_assertion = 0) :
2.434 + assertion(_assertion), file(_file), line(_line), function(func),
2.435 + message(msg) {}
2.436 +
2.437 + ///\e
2.438 + const char* get_assertion() const { return assertion; }
2.439 + ///\e
2.440 + const char* get_message() const { return message; }
2.441 + ///\e
2.442 + const char* get_file() const { return file; }
2.443 + ///\e
2.444 + const char* get_function() const { return function; }
2.445 + ///\e
2.446 + int get_line() const { return line; }
2.447 +
2.448 +
2.449 + virtual const char* what() const throw() {
2.450 + try {
2.451 + std::ostringstream ostr;
2.452 + ostr << file << ":" << line << ": ";
2.453 + if( function )
2.454 + ostr << function << ": ";
2.455 + ostr << message;
2.456 + if( assertion )
2.457 + ostr << " (assertion '" << assertion << "' failed)";
2.458 + _message_holder.set(ostr.str());
2.459 + return ostr.str().c_str();
2.460 + }
2.461 + catch(...) {}
2.462 + if( _message_holder.valid() ) return _message_holder.get().c_str();
2.463 + return "lemon::AssertionFailedError";
2.464 + }
2.465 + virtual ~AssertionFailedError() throw() {}
2.466 + };
2.467 +
2.468 +
2.469 + /**************** Macros ****************/
2.470 +
2.471 +
2.472 + template <typename Exception>
2.473 + inline void assert_fail(const char *file, int line,
2.474 + const char *func,
2.475 + Exception exception,
2.476 + const char *assertion = 0,
2.477 + bool do_abort=true)
2.478 + {
2.479 + using namespace std;
2.480 + cerr << file << ":" << line << ": ";
2.481 + if (func)
2.482 + cerr << func << ": ";
2.483 + cerr << exception.what();
2.484 + if (assertion)
2.485 + cerr << " (assertion '" << assertion << "' failed)";
2.486 + cerr << endl;
2.487 + if (do_abort)
2.488 + abort();
2.489 + }
2.490 +
2.491 + template <>
2.492 + inline void assert_fail<const char *>(const char *file, int line,
2.493 + const char *func,
2.494 + const char *message,
2.495 + const char *assertion,
2.496 + bool do_abort)
2.497 + {
2.498 + using namespace std;
2.499 + cerr << file << ":" << line << ": ";
2.500 + if (func)
2.501 + cerr << func << ": ";
2.502 + cerr << message;
2.503 + if (assertion)
2.504 + cerr << " (assertion '" << assertion << "' failed)";
2.505 + cerr << endl;
2.506 + if (do_abort)
2.507 + abort();
2.508 + }
2.509 +
2.510 + template <>
2.511 + inline void assert_fail<std::string>(const char *file, int line,
2.512 + const char *func,
2.513 + std::string message,
2.514 + const char *assertion,
2.515 + bool do_abort)
2.516 + {
2.517 + assert_fail(file, line, func, message.c_str(), assertion, do_abort);
2.518 + }
2.519 +
2.520 + template <typename Exception>
2.521 + inline void assert_fail_failure(const char *file, int line, const char *func,
2.522 + Exception exception,
2.523 + const char *assertion = 0,
2.524 + bool = true)
2.525 + {
2.526 + throw AssertionFailedError(file, line, func, exception.what(), assertion);
2.527 + }
2.528 +
2.529 + template <>
2.530 + inline void assert_fail_failure<const char *>(const char *file, int line,
2.531 + const char *func,
2.532 + const char *message,
2.533 + const char *assertion,
2.534 + bool)
2.535 + {
2.536 + throw AssertionFailedError(file, line, func, message, assertion);
2.537 + }
2.538 +
2.539 + template <>
2.540 + inline void assert_fail_failure<std::string>(const char *file, int line,
2.541 + const char *func,
2.542 + std::string message,
2.543 + const char *assertion,
2.544 + bool)
2.545 + {
2.546 + assert_fail_failure(file, line, func, message.c_str(), assertion, true);
2.547 + }
2.548 +
2.549 + template <typename Exception>
2.550 + inline void assert_fail_exception(const char *file, int line, const char *func,
2.551 + Exception exception,
2.552 + const char *assertion = 0, bool = true)
2.553 + {
2.554 + throw exception;
2.555 + }
2.556 +
2.557 + template <>
2.558 + inline void assert_fail_exception<const char *>(const char *file, int line,
2.559 + const char *func,
2.560 + const char *message,
2.561 + const char *assertion,
2.562 + bool)
2.563 + {
2.564 + throw AssertionFailedError(file, line, func, message, assertion);
2.565 + }
2.566 +
2.567 + template <>
2.568 + inline void assert_fail_exception<std::string>(const char *file, int line,
2.569 + const char *func,
2.570 + std::string message,
2.571 + const char *assertion,
2.572 + bool)
2.573 + {
2.574 + assert_fail_exception(file, line, func, message.c_str(), assertion, true);
2.575 + }
2.576 +
2.577 +/// @}
2.578 +
2.579 +}
2.580 +#endif // LEMON_ERROR_H
2.581 +
2.582 +#undef LEMON_ASSERT
2.583 +#undef LEMON_FIXME
2.584 +
2.585 +#ifdef LEMON_ENABLE_ASSERTS
2.586 +# define LEMON_ASSERT_ABORT
2.587 +#endif
2.588 +
2.589 +#ifndef LEMON_ASSERT_DO_ABORT
2.590 +# define LEMON_ASSERT_DO_ABORT 1
2.591 +#endif
2.592 +
2.593 +#ifndef LEMON_ASSERT_HANDLER
2.594 +# if defined LEMON_ASSERT_EXCEPTION
2.595 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
2.596 +# elif defined LEMON_ASSERT_FAILURE
2.597 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
2.598 +# elif defined LEMON_ASSERT_ABORT
2.599 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
2.600 +# else
2.601 +# define LEMON_DISABLE_ASSERTS
2.602 +# endif
2.603 +#endif
2.604 +
2.605 +#ifdef DOXYGEN
2.606 +
2.607 +/// \brief Macro for assertions with customizable message
2.608 +///
2.609 +/// Macro for assertions with customizable message.
2.610 +///
2.611 +/// The assertions are disabled in the default behaviour. You can
2.612 +/// enable the assertions with the
2.613 +/// \code
2.614 +/// #define LEMON_ENABLE_ASSERTS
2.615 +/// \endcode
2.616 +/// Then an assert
2.617 +/// provides a log on the standard error about the assertion and aborts
2.618 +/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the
2.619 +/// program keeps on running).
2.620 +/// By defining LEMON_ASSERT_FAILURE or
2.621 +/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the
2.622 +/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT
2.623 +/// will always throw an \c AssertionFailedError exception with
2.624 +/// the \c msg error message. By using
2.625 +/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.
2.626 +///
2.627 +/// The LEMON_ASSERT macro should be called with the \c exp parameter
2.628 +/// which should be an expression convertible to bool. If the given
2.629 +/// parameter is false the assertion is raised and one of the assertion
2.630 +/// behaviour will be activated. The \c msg should be either a const
2.631 +/// char* message or an exception. When the \c msg is an exception the
2.632 +/// \ref lemon::Exception::what() "what()" function is called to retrieve and
2.633 +/// display the error message.
2.634 +///
2.635 +/// \todo We should provide some way to reset to the default behaviour,
2.636 +/// shouldn't we?
2.637 +///
2.638 +/// \todo This whole 'assert' business should be placed in a separate
2.639 +/// include file. The boost assert is not guarded by header sentries
2.640 +/// which may help to change the behaviour of the assertions in
2.641 +/// the files.
2.642 +///
2.643 +/// \todo __PRETTY_FUNCTION__ should be replaced by something
2.644 +/// compiler-independent, like BOOST_CURRENT_FUNCTION
2.645 +
2.646 +# define LEMON_ASSERT(exp, msg) \
2.647 + (static_cast<void> (!!(exp) ? 0 : ( \
2.648 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
2.649 + __PRETTY_FUNCTION__, \
2.650 + msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
2.651 +
2.652 +#else
2.653 +# if defined LEMON_DISABLE_ASSERTS
2.654 +
2.655 +# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
2.656 +
2.657 +# else
2.658 +# define LEMON_ASSERT(exp, msg) \
2.659 + (static_cast<void> (!!(exp) ? 0 : ( \
2.660 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
2.661 + __PRETTY_FUNCTION__, \
2.662 + msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
2.663 +# endif
2.664 +#endif
2.665 +
2.666 +/**
2.667 + * \brief Macro for mark not yet implemented features.
2.668 + *
2.669 + * \todo Is this the right place for this? It should be used only in
2.670 + * modules under development.
2.671 + *
2.672 + * \todo __PRETTY_FUNCTION__ should be replaced by something
2.673 + * compiler-independent, like BOOST_CURRENT_FUNCTION
2.674 + */
2.675 +
2.676 +#define LEMON_FIXME(msg) \
2.677 + (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
2.678 + "FIXME: " msg))
3.1 --- a/test/Makefile.am Mon Feb 04 13:32:36 2008 +0100
3.2 +++ b/test/Makefile.am Thu Feb 07 11:52:16 2008 +0000
3.3 @@ -19,6 +19,7 @@
3.4
3.5 test_digraph_test_SOURCES = test/digraph_test.cc
3.6 test_dim_test_SOURCES = test/dim_test.cc
3.7 +#test_error_test_SOURCES = test/error_test.cc
3.8 test_graph_test_SOURCES = test/graph_test.cc
3.9 test_random_test_SOURCES = test/random_test.cc
3.10 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/test/error_test.cc Thu Feb 07 11:52:16 2008 +0000
4.3 @@ -0,0 +1,68 @@
4.4 +/* -*- C++ -*-
4.5 + *
4.6 + * This file is a part of LEMON, a generic C++ optimization library
4.7 + *
4.8 + * Copyright (C) 2003-2008
4.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
4.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
4.11 + *
4.12 + * Permission to use, modify and distribute this software is granted
4.13 + * provided that this copyright notice appears in all copies. For
4.14 + * precise terms see the accompanying LICENSE file.
4.15 + *
4.16 + * This software is provided "AS IS" with no warranty of any kind,
4.17 + * express or implied, and with no claim as to its suitability for any
4.18 + * purpose.
4.19 + *
4.20 + */
4.21 +
4.22 +#include <iostream>
4.23 +
4.24 +#include <lemon/error.h>
4.25 +#include "test_tools.h"
4.26 +
4.27 +using namespace lemon;
4.28 +using std::cout;
4.29 +using std::endl;
4.30 +
4.31 +void faulty_fn() {
4.32 + fault("This is a fault message");
4.33 +}
4.34 +
4.35 +void exception_fn() {
4.36 + throw Exception("This is a function throwing exception with some args: ")
4.37 + << 5 << ", " << 18;
4.38 +}
4.39 +
4.40 +void unfinished_fn() {
4.41 + LEMON_FIXME("unfinished_fn() is unfinished!");
4.42 +}
4.43 +
4.44 +
4.45 +int main() {
4.46 + try {
4.47 + faulty_fn();
4.48 + check(false, "A faulty function did not fail.");
4.49 + }
4.50 + catch(const Exception &e) {
4.51 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
4.52 + }
4.53 +
4.54 + try {
4.55 + exception_fn();
4.56 + check(false, "The function did not throw Exception.");
4.57 + }
4.58 + catch(const Exception &e) {
4.59 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
4.60 + }
4.61 +
4.62 + try {
4.63 + unfinished_fn();
4.64 + check(false, "FIXME macro does not work.");
4.65 + }
4.66 + catch(const Exception &e) {
4.67 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
4.68 + }
4.69 +
4.70 + return 0;
4.71 +}