1.1 --- a/configure.ac Thu Jan 24 17:36:45 2008 +0000
1.2 +++ b/configure.ac Thu Feb 07 21:28:39 2008 +0000
1.3 @@ -13,7 +13,7 @@
1.4 AC_INIT([LEMON], [lemon_version()], [etik-ol@cs.elte.hu], [lemon])
1.5 AC_CONFIG_AUX_DIR([build-aux])
1.6 AC_CONFIG_MACRO_DIR([m4])
1.7 -AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
1.8 +AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
1.9 AC_CONFIG_SRCDIR([lemon/list_graph.h])
1.10 AC_CONFIG_HEADERS([config.h lemon/config.h])
1.11
2.1 --- a/lemon/Makefile.am Thu Jan 24 17:36:45 2008 +0000
2.2 +++ b/lemon/Makefile.am Thu Feb 07 21:28:39 2008 +0000
2.3 @@ -15,11 +15,13 @@
2.4 lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
2.5
2.6 lemon_HEADERS += \
2.7 + lemon/concept_check.h \
2.8 lemon/dim2.h \
2.9 + lemon/error.h \
2.10 + lemon/list_graph.h \
2.11 lemon/maps.h \
2.12 lemon/path.h \
2.13 lemon/random.h \
2.14 - lemon/list_graph.h \
2.15 lemon/tolerance.h
2.16
2.17 bits_HEADERS += \
3.1 --- a/lemon/concepts/digraph.h Thu Jan 24 17:36:45 2008 +0000
3.2 +++ b/lemon/concepts/digraph.h Thu Feb 07 21:28:39 2008 +0000
3.3 @@ -348,6 +348,28 @@
3.4 ///
3.5 Node source(Arc) const { return INVALID; }
3.6
3.7 + /// \brief Returns the ID of the node.
3.8 + int id(Node) const { return -1; }
3.9 +
3.10 + /// \brief Returns the ID of the arc.
3.11 + int id(Arc) const { return -1; }
3.12 +
3.13 + /// \brief Returns the node with the given ID.
3.14 + ///
3.15 + /// \pre The argument should be a valid node ID in the graph.
3.16 + Node nodeFromId(int) const { return INVALID; }
3.17 +
3.18 + /// \brief Returns the arc with the given ID.
3.19 + ///
3.20 + /// \pre The argument should be a valid arc ID in the graph.
3.21 + Arc arcFromId(int) const { return INVALID; }
3.22 +
3.23 + /// \brief Returns an upper bound on the node IDs.
3.24 + int maxNodeId() const { return -1; }
3.25 +
3.26 + /// \brief Returns an upper bound on the arc IDs.
3.27 + int maxArcId() const { return -1; }
3.28 +
3.29 void first(Node&) const {}
3.30 void next(Node&) const {}
3.31
3.32 @@ -361,6 +383,16 @@
3.33 void firstOut(Arc&, const Node&) const {}
3.34 void nextOut(Arc&) const {}
3.35
3.36 + // The second parameter is dummy.
3.37 + Node fromId(int, Node) const { return INVALID; }
3.38 + // The second parameter is dummy.
3.39 + Arc fromId(int, Arc) const { return INVALID; }
3.40 +
3.41 + // Dummy parameter.
3.42 + int maxId(Node) const { return -1; }
3.43 + // Dummy parameter.
3.44 + int maxId(Arc) const { return -1; }
3.45 +
3.46 /// \brief The base node of the iterator.
3.47 ///
3.48 /// Gives back the base node of the iterator.
3.49 @@ -439,6 +471,7 @@
3.50 struct Constraints {
3.51 void constraints() {
3.52 checkConcept<IterableDigraphComponent<>, Digraph>();
3.53 + checkConcept<IDableDigraphComponent<>, Digraph>();
3.54 checkConcept<MappableDigraphComponent<>, Digraph>();
3.55 }
3.56 };
4.1 --- a/lemon/concepts/graph.h Thu Jan 24 17:36:45 2008 +0000
4.2 +++ b/lemon/concepts/graph.h Thu Feb 07 21:28:39 2008 +0000
4.3 @@ -624,6 +624,39 @@
4.4 /// \brief Target node of the directed arc.
4.5 Node target(Arc) const { return INVALID; }
4.6
4.7 + /// \brief Returns the id of the node.
4.8 + int id(Node) const { return -1; }
4.9 +
4.10 + /// \brief Returns the id of the edge.
4.11 + int id(Edge) const { return -1; }
4.12 +
4.13 + /// \brief Returns the id of the arc.
4.14 + int id(Arc) const { return -1; }
4.15 +
4.16 + /// \brief Returns the node with the given id.
4.17 + ///
4.18 + /// \pre The argument should be a valid node id in the graph.
4.19 + Node nodeFromId(int) const { return INVALID; }
4.20 +
4.21 + /// \brief Returns the edge with the given id.
4.22 + ///
4.23 + /// \pre The argument should be a valid edge id in the graph.
4.24 + Edge edgeFromId(int) const { return INVALID; }
4.25 +
4.26 + /// \brief Returns the arc with the given id.
4.27 + ///
4.28 + /// \pre The argument should be a valid arc id in the graph.
4.29 + Arc arcFromId(int) const { return INVALID; }
4.30 +
4.31 + /// \brief Returns an upper bound on the node IDs.
4.32 + int maxNodeId() const { return -1; }
4.33 +
4.34 + /// \brief Returns an upper bound on the edge IDs.
4.35 + int maxEdgeId() const { return -1; }
4.36 +
4.37 + /// \brief Returns an upper bound on the arc IDs.
4.38 + int maxArcId() const { return -1; }
4.39 +
4.40 void first(Node&) const {}
4.41 void next(Node&) const {}
4.42
4.43 @@ -639,10 +672,23 @@
4.44 void firstIn(Arc&, Node) const {}
4.45 void nextIn(Arc&) const {}
4.46
4.47 -
4.48 void firstInc(Edge &, bool &, const Node &) const {}
4.49 void nextInc(Edge &, bool &) const {}
4.50
4.51 + // The second parameter is dummy.
4.52 + Node fromId(int, Node) const { return INVALID; }
4.53 + // The second parameter is dummy.
4.54 + Edge fromId(int, Edge) const { return INVALID; }
4.55 + // The second parameter is dummy.
4.56 + Arc fromId(int, Arc) const { return INVALID; }
4.57 +
4.58 + // Dummy parameter.
4.59 + int maxId(Node) const { return -1; }
4.60 + // Dummy parameter.
4.61 + int maxId(Edge) const { return -1; }
4.62 + // Dummy parameter.
4.63 + int maxId(Arc) const { return -1; }
4.64 +
4.65 /// \brief Base node of the iterator
4.66 ///
4.67 /// Returns the base node (the source in this case) of the iterator
4.68 @@ -689,6 +735,7 @@
4.69 struct Constraints {
4.70 void constraints() {
4.71 checkConcept<IterableGraphComponent<>, Graph>();
4.72 + checkConcept<IDableGraphComponent<>, Graph>();
4.73 checkConcept<MappableGraphComponent<>, Graph>();
4.74 }
4.75 };
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/lemon/error.h Thu Feb 07 21:28:39 2008 +0000
5.3 @@ -0,0 +1,675 @@
5.4 +/* -*- C++ -*-
5.5 + *
5.6 + * This file is a part of LEMON, a generic C++ optimization library
5.7 + *
5.8 + * Copyright (C) 2003-2008
5.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
5.11 + *
5.12 + * Permission to use, modify and distribute this software is granted
5.13 + * provided that this copyright notice appears in all copies. For
5.14 + * precise terms see the accompanying LICENSE file.
5.15 + *
5.16 + * This software is provided "AS IS" with no warranty of any kind,
5.17 + * express or implied, and with no claim as to its suitability for any
5.18 + * purpose.
5.19 + *
5.20 + */
5.21 +
5.22 +#ifndef LEMON_ERROR_H
5.23 +#define LEMON_ERROR_H
5.24 +
5.25 +/// \ingroup exceptions
5.26 +/// \file
5.27 +/// \brief Basic exception classes and error handling.
5.28 +
5.29 +#include <exception>
5.30 +#include <string>
5.31 +#include <sstream>
5.32 +#include <iostream>
5.33 +#include <cstdlib>
5.34 +#include <memory>
5.35 +
5.36 +namespace lemon {
5.37 +
5.38 + /// \addtogroup exceptions
5.39 + /// @{
5.40 +
5.41 + /// \brief Exception safe wrapper class.
5.42 + ///
5.43 + /// Exception safe wrapper class to implement the members of exceptions.
5.44 + template <typename _Type>
5.45 + class ExceptionMember {
5.46 + public:
5.47 + typedef _Type Type;
5.48 +
5.49 + ExceptionMember() throw() {
5.50 + try {
5.51 + ptr.reset(new Type());
5.52 + } catch (...) {}
5.53 + }
5.54 +
5.55 + ExceptionMember(const Type& type) throw() {
5.56 + try {
5.57 + ptr.reset(new Type());
5.58 + if (ptr.get() == 0) return;
5.59 + *ptr = type;
5.60 + } catch (...) {}
5.61 + }
5.62 +
5.63 + ExceptionMember(const ExceptionMember& copy) throw() {
5.64 + try {
5.65 + if (!copy.valid()) return;
5.66 + ptr.reset(new Type());
5.67 + if (ptr.get() == 0) return;
5.68 + *ptr = copy.get();
5.69 + } catch (...) {}
5.70 + }
5.71 +
5.72 + ExceptionMember& operator=(const ExceptionMember& copy) throw() {
5.73 + if (ptr.get() == 0) return;
5.74 + try {
5.75 + if (!copy.valid()) return;
5.76 + *ptr = copy.get();
5.77 + } catch (...) {}
5.78 + }
5.79 +
5.80 + void set(const Type& type) throw() {
5.81 + if (ptr.get() == 0) return;
5.82 + try {
5.83 + *ptr = type;
5.84 + } catch (...) {}
5.85 + }
5.86 +
5.87 + const Type& get() const {
5.88 + return *ptr;
5.89 + }
5.90 +
5.91 + bool valid() const throw() {
5.92 + return ptr.get() != 0;
5.93 + }
5.94 +
5.95 + private:
5.96 + std::auto_ptr<_Type> ptr;
5.97 + };
5.98 +
5.99 + /// Exception-safe convenient "error message" class.
5.100 +
5.101 + /// Helper class which provides a convenient ostream-like (operator <<
5.102 + /// based) interface to create a string message. Mostly useful in
5.103 + /// exception classes (therefore the name).
5.104 + class ErrorMessage {
5.105 + protected:
5.106 + ///\e
5.107 +
5.108 + ///\todo The good solution is boost::shared_ptr...
5.109 + ///
5.110 + mutable std::auto_ptr<std::ostringstream> buf;
5.111 +
5.112 + ///\e
5.113 + bool init() throw() {
5.114 + try {
5.115 + buf.reset(new std::ostringstream);
5.116 + }
5.117 + catch(...) {
5.118 + buf.reset();
5.119 + }
5.120 + return buf.get();
5.121 + }
5.122 +
5.123 + public:
5.124 +
5.125 + ///\e
5.126 + ErrorMessage() throw() { init(); }
5.127 +
5.128 + ErrorMessage(const ErrorMessage& em) throw() : buf(em.buf) { }
5.129 +
5.130 + ///\e
5.131 + ErrorMessage(const char *msg) throw() {
5.132 + init();
5.133 + *this << msg;
5.134 + }
5.135 +
5.136 + ///\e
5.137 + ErrorMessage(const std::string &msg) throw() {
5.138 + init();
5.139 + *this << msg;
5.140 + }
5.141 +
5.142 + ///\e
5.143 + template <typename T>
5.144 + ErrorMessage& operator<<(const T &t) throw() {
5.145 + if( ! buf.get() ) return *this;
5.146 +
5.147 + try {
5.148 + *buf << t;
5.149 + }
5.150 + catch(...) {
5.151 + buf.reset();
5.152 + }
5.153 + return *this;
5.154 + }
5.155 +
5.156 + ///\e
5.157 + const char* message() throw() {
5.158 + if( ! buf.get() ) return 0;
5.159 +
5.160 + const char* mes = 0;
5.161 + try {
5.162 + mes = buf->str().c_str();
5.163 + }
5.164 + catch(...) {}
5.165 + return mes;
5.166 + }
5.167 +
5.168 + };
5.169 +
5.170 + /// Generic exception class.
5.171 +
5.172 + /// Base class for exceptions used in LEMON.
5.173 + ///
5.174 + class Exception : public std::exception {
5.175 + public:
5.176 + ///\e
5.177 + Exception() {}
5.178 + ///\e
5.179 + virtual ~Exception() throw() {}
5.180 + ///\e
5.181 + virtual const char* what() const throw() {
5.182 + return "lemon::Exception";
5.183 + }
5.184 + };
5.185 +
5.186 + /// One of the two main subclasses of \ref Exception.
5.187 +
5.188 + /// Logic errors represent problems in the internal logic of a program;
5.189 + /// in theory, these are preventable, and even detectable before the
5.190 + /// program runs (e.g. violations of class invariants).
5.191 + ///
5.192 + /// A typical example for this is \ref UninitializedParameter.
5.193 + class LogicError : public Exception {
5.194 + public:
5.195 + virtual const char* what() const throw() {
5.196 + return "lemon::LogicError";
5.197 + }
5.198 + };
5.199 +
5.200 + /// \ref Exception for uninitialized parameters.
5.201 +
5.202 + /// This error represents problems in the initialization
5.203 + /// of the parameters of the algorithms.
5.204 + class UninitializedParameter : public LogicError {
5.205 + public:
5.206 + virtual const char* what() const throw() {
5.207 + return "lemon::UninitializedParameter";
5.208 + }
5.209 + };
5.210 +
5.211 +
5.212 + /// One of the two main subclasses of \ref Exception.
5.213 +
5.214 + /// Runtime errors represent problems outside the scope of a program;
5.215 + /// they cannot be easily predicted and can generally only be caught
5.216 + /// as the program executes.
5.217 + class RuntimeError : public Exception {
5.218 + public:
5.219 + virtual const char* what() const throw() {
5.220 + return "lemon::RuntimeError";
5.221 + }
5.222 + };
5.223 +
5.224 + ///\e
5.225 + class RangeError : public RuntimeError {
5.226 + public:
5.227 + virtual const char* what() const throw() {
5.228 + return "lemon::RangeError";
5.229 + }
5.230 + };
5.231 +
5.232 + ///\e
5.233 + class IoError : public RuntimeError {
5.234 + public:
5.235 + virtual const char* what() const throw() {
5.236 + return "lemon::IoError";
5.237 + }
5.238 + };
5.239 +
5.240 + ///\e
5.241 + class DataFormatError : public IoError {
5.242 + protected:
5.243 + ExceptionMember<std::string> _message;
5.244 + ExceptionMember<std::string> _file;
5.245 + int _line;
5.246 +
5.247 + mutable ExceptionMember<std::string> _message_holder;
5.248 + public:
5.249 +
5.250 + DataFormatError(const DataFormatError &dfe) :
5.251 + IoError(dfe), _message(dfe._message), _file(dfe._file),
5.252 + _line(dfe._line) {}
5.253 +
5.254 + ///\e
5.255 + explicit DataFormatError(const char *the_message)
5.256 + : _message(the_message), _line(0) {}
5.257 +
5.258 + ///\e
5.259 + DataFormatError(const std::string &file_name, int line_num,
5.260 + const char *the_message)
5.261 + : _message(the_message), _line(line_num) { file(file_name); }
5.262 +
5.263 + ///\e
5.264 + void line(int ln) { _line = ln; }
5.265 + ///\e
5.266 + void message(const std::string& msg) { _message.set(msg); }
5.267 + ///\e
5.268 + void file(const std::string &fl) { _file.set(fl); }
5.269 +
5.270 + ///\e
5.271 + int line() const { return _line; }
5.272 + ///\e
5.273 + const char* message() const {
5.274 + if (_message.valid() && !_message.get().empty()) {
5.275 + return _message.get().c_str();
5.276 + } else {
5.277 + return 0;
5.278 + }
5.279 + }
5.280 +
5.281 + /// \brief Returns the filename.
5.282 + ///
5.283 + /// Returns \e null if the filename was not specified.
5.284 + const char* file() const {
5.285 + if (_file.valid() && !_file.get().empty()) {
5.286 + return _file.get().c_str();
5.287 + } else {
5.288 + return 0;
5.289 + }
5.290 + }
5.291 +
5.292 + ///\e
5.293 + virtual const char* what() const throw() {
5.294 + try {
5.295 + std::ostringstream ostr;
5.296 + ostr << "lemon:DataFormatError" << ": ";
5.297 + if (message()) ostr << message();
5.298 + if( file() || line() != 0 ) {
5.299 + ostr << " (";
5.300 + if( file() ) ostr << "in file '" << file() << "'";
5.301 + if( file() && line() != 0 ) ostr << " ";
5.302 + if( line() != 0 ) ostr << "at line " << line();
5.303 + ostr << ")";
5.304 + }
5.305 + _message_holder.set(ostr.str());
5.306 + }
5.307 + catch (...) {}
5.308 + if( _message_holder.valid()) return _message_holder.get().c_str();
5.309 + return "lemon:DataFormatError";
5.310 + }
5.311 +
5.312 + virtual ~DataFormatError() throw() {}
5.313 + };
5.314 +
5.315 + ///\e
5.316 + class FileOpenError : public IoError {
5.317 + protected:
5.318 + ExceptionMember<std::string> _file;
5.319 +
5.320 + mutable ExceptionMember<std::string> _message_holder;
5.321 + public:
5.322 +
5.323 + FileOpenError(const FileOpenError &foe) :
5.324 + IoError(foe), _file(foe._file) {}
5.325 +
5.326 + ///\e
5.327 + explicit FileOpenError(const std::string& fl)
5.328 + : _file(fl) {}
5.329 +
5.330 +
5.331 + ///\e
5.332 + void file(const std::string &fl) { _file.set(fl); }
5.333 +
5.334 + /// \brief Returns the filename.
5.335 + ///
5.336 + /// Returns \e null if the filename was not specified.
5.337 + const char* file() const {
5.338 + if (_file.valid() && !_file.get().empty()) {
5.339 + return _file.get().c_str();
5.340 + } else {
5.341 + return 0;
5.342 + }
5.343 + }
5.344 +
5.345 + ///\e
5.346 + virtual const char* what() const throw() {
5.347 + try {
5.348 + std::ostringstream ostr;
5.349 + ostr << "lemon::FileOpenError" << ": ";
5.350 + ostr << "Cannot open file - " << file();
5.351 + _message_holder.set(ostr.str());
5.352 + }
5.353 + catch (...) {}
5.354 + if( _message_holder.valid()) return _message_holder.get().c_str();
5.355 + return "lemon::FileOpenError";
5.356 + }
5.357 + virtual ~FileOpenError() throw() {}
5.358 + };
5.359 +
5.360 + class IoParameterError : public IoError {
5.361 + protected:
5.362 + ExceptionMember<std::string> _message;
5.363 + ExceptionMember<std::string> _file;
5.364 +
5.365 + mutable ExceptionMember<std::string> _message_holder;
5.366 + public:
5.367 +
5.368 + IoParameterError(const IoParameterError &ile) :
5.369 + IoError(ile), _message(ile._message), _file(ile._file) {}
5.370 +
5.371 + ///\e
5.372 + explicit IoParameterError(const char *the_message)
5.373 + : _message(the_message) {}
5.374 +
5.375 + ///\e
5.376 + IoParameterError(const char *file_name, const char *the_message)
5.377 + : _message(the_message), _file(file_name) {}
5.378 +
5.379 + ///\e
5.380 + void message(const std::string& msg) { _message.set(msg); }
5.381 + ///\e
5.382 + void file(const std::string &fl) { _file.set(fl); }
5.383 +
5.384 + ///\e
5.385 + const char* message() const {
5.386 + if (_message.valid()) {
5.387 + return _message.get().c_str();
5.388 + } else {
5.389 + return 0;
5.390 + }
5.391 + }
5.392 +
5.393 + /// \brief Returns the filename.
5.394 + ///
5.395 + /// Returns \c 0 if the filename was not specified.
5.396 + const char* file() const {
5.397 + if (_file.valid()) {
5.398 + return _file.get().c_str();
5.399 + } else {
5.400 + return 0;
5.401 + }
5.402 + }
5.403 +
5.404 + ///\e
5.405 + virtual const char* what() const throw() {
5.406 + try {
5.407 + std::ostringstream ostr;
5.408 + if (message()) ostr << message();
5.409 + if (file()) ostr << "(when reading file '" << file() << "')";
5.410 + _message_holder.set(ostr.str());
5.411 + }
5.412 + catch (...) {}
5.413 + if( _message_holder.valid() ) return _message_holder.get().c_str();
5.414 + return "lemon:IoParameterError";
5.415 + }
5.416 + virtual ~IoParameterError() throw() {}
5.417 + };
5.418 +
5.419 +
5.420 + ///\e
5.421 + class AssertionFailedError : public LogicError {
5.422 + protected:
5.423 + const char *assertion;
5.424 + const char *file;
5.425 + int line;
5.426 + const char *function;
5.427 + const char *message;
5.428 +
5.429 + mutable ExceptionMember<std::string> _message_holder;
5.430 + public:
5.431 + ///\e
5.432 + AssertionFailedError(const char *_file, int _line, const char *func,
5.433 + const char *msg, const char *_assertion = 0) :
5.434 + assertion(_assertion), file(_file), line(_line), function(func),
5.435 + message(msg) {}
5.436 +
5.437 + ///\e
5.438 + const char* get_assertion() const { return assertion; }
5.439 + ///\e
5.440 + const char* get_message() const { return message; }
5.441 + ///\e
5.442 + const char* get_file() const { return file; }
5.443 + ///\e
5.444 + const char* get_function() const { return function; }
5.445 + ///\e
5.446 + int get_line() const { return line; }
5.447 +
5.448 +
5.449 + virtual const char* what() const throw() {
5.450 + try {
5.451 + std::ostringstream ostr;
5.452 + ostr << file << ":" << line << ": ";
5.453 + if( function )
5.454 + ostr << function << ": ";
5.455 + ostr << message;
5.456 + if( assertion )
5.457 + ostr << " (assertion '" << assertion << "' failed)";
5.458 + _message_holder.set(ostr.str());
5.459 + return ostr.str().c_str();
5.460 + }
5.461 + catch(...) {}
5.462 + if( _message_holder.valid() ) return _message_holder.get().c_str();
5.463 + return "lemon::AssertionFailedError";
5.464 + }
5.465 + virtual ~AssertionFailedError() throw() {}
5.466 + };
5.467 +
5.468 +
5.469 + /**************** Macros ****************/
5.470 +
5.471 +
5.472 + template <typename Exception>
5.473 + inline void assert_fail(const char *file, int line,
5.474 + const char *func,
5.475 + Exception exception,
5.476 + const char *assertion = 0,
5.477 + bool do_abort=true)
5.478 + {
5.479 + using namespace std;
5.480 + cerr << file << ":" << line << ": ";
5.481 + if (func)
5.482 + cerr << func << ": ";
5.483 + cerr << exception.what();
5.484 + if (assertion)
5.485 + cerr << " (assertion '" << assertion << "' failed)";
5.486 + cerr << endl;
5.487 + if (do_abort)
5.488 + abort();
5.489 + }
5.490 +
5.491 + template <>
5.492 + inline void assert_fail<const char *>(const char *file, int line,
5.493 + const char *func,
5.494 + const char *message,
5.495 + const char *assertion,
5.496 + bool do_abort)
5.497 + {
5.498 + using namespace std;
5.499 + cerr << file << ":" << line << ": ";
5.500 + if (func)
5.501 + cerr << func << ": ";
5.502 + cerr << message;
5.503 + if (assertion)
5.504 + cerr << " (assertion '" << assertion << "' failed)";
5.505 + cerr << endl;
5.506 + if (do_abort)
5.507 + abort();
5.508 + }
5.509 +
5.510 + template <>
5.511 + inline void assert_fail<std::string>(const char *file, int line,
5.512 + const char *func,
5.513 + std::string message,
5.514 + const char *assertion,
5.515 + bool do_abort)
5.516 + {
5.517 + assert_fail(file, line, func, message.c_str(), assertion, do_abort);
5.518 + }
5.519 +
5.520 + template <typename Exception>
5.521 + inline void assert_fail_failure(const char *file, int line, const char *func,
5.522 + Exception exception,
5.523 + const char *assertion = 0,
5.524 + bool = true)
5.525 + {
5.526 + throw AssertionFailedError(file, line, func, exception.what(), assertion);
5.527 + }
5.528 +
5.529 + template <>
5.530 + inline void assert_fail_failure<const char *>(const char *file, int line,
5.531 + const char *func,
5.532 + const char *message,
5.533 + const char *assertion,
5.534 + bool)
5.535 + {
5.536 + throw AssertionFailedError(file, line, func, message, assertion);
5.537 + }
5.538 +
5.539 + template <>
5.540 + inline void assert_fail_failure<std::string>(const char *file, int line,
5.541 + const char *func,
5.542 + std::string message,
5.543 + const char *assertion,
5.544 + bool)
5.545 + {
5.546 + assert_fail_failure(file, line, func, message.c_str(), assertion, true);
5.547 + }
5.548 +
5.549 + template <typename Exception>
5.550 + inline void assert_fail_exception(const char *file, int line, const char *func,
5.551 + Exception exception,
5.552 + const char *assertion = 0, bool = true)
5.553 + {
5.554 + throw exception;
5.555 + }
5.556 +
5.557 + template <>
5.558 + inline void assert_fail_exception<const char *>(const char *file, int line,
5.559 + const char *func,
5.560 + const char *message,
5.561 + const char *assertion,
5.562 + bool)
5.563 + {
5.564 + throw AssertionFailedError(file, line, func, message, assertion);
5.565 + }
5.566 +
5.567 + template <>
5.568 + inline void assert_fail_exception<std::string>(const char *file, int line,
5.569 + const char *func,
5.570 + std::string message,
5.571 + const char *assertion,
5.572 + bool)
5.573 + {
5.574 + assert_fail_exception(file, line, func, message.c_str(), assertion, true);
5.575 + }
5.576 +
5.577 +/// @}
5.578 +
5.579 +}
5.580 +#endif // LEMON_ERROR_H
5.581 +
5.582 +#undef LEMON_ASSERT
5.583 +#undef LEMON_FIXME
5.584 +
5.585 +#ifdef LEMON_ENABLE_ASSERTS
5.586 +# define LEMON_ASSERT_ABORT
5.587 +#endif
5.588 +
5.589 +#ifndef LEMON_ASSERT_DO_ABORT
5.590 +# define LEMON_ASSERT_DO_ABORT 1
5.591 +#endif
5.592 +
5.593 +#ifndef LEMON_ASSERT_HANDLER
5.594 +# if defined LEMON_ASSERT_EXCEPTION
5.595 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
5.596 +# elif defined LEMON_ASSERT_FAILURE
5.597 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail_failure
5.598 +# elif defined LEMON_ASSERT_ABORT
5.599 +# define LEMON_ASSERT_HANDLER ::lemon::assert_fail
5.600 +# else
5.601 +# define LEMON_DISABLE_ASSERTS
5.602 +# endif
5.603 +#endif
5.604 +
5.605 +#ifdef DOXYGEN
5.606 +
5.607 +/// \brief Macro for assertions with customizable message
5.608 +///
5.609 +/// Macro for assertions with customizable message.
5.610 +///
5.611 +/// The assertions are disabled in the default behaviour. You can
5.612 +/// enable the assertions with the
5.613 +/// \code
5.614 +/// #define LEMON_ENABLE_ASSERTS
5.615 +/// \endcode
5.616 +/// Then an assert
5.617 +/// provides a log on the standard error about the assertion and aborts
5.618 +/// the program if LEMON_ASSERT_DO_ABORT is also defined (otherwise the
5.619 +/// program keeps on running).
5.620 +/// By defining LEMON_ASSERT_FAILURE or
5.621 +/// LEMON_ASSERT_EXCEPTION, you can set other behaviour to the
5.622 +/// assertions. In case LEMON_ASSERT_FAILURE is given, LEMON_ASSERT
5.623 +/// will always throw an \c AssertionFailedError exception with
5.624 +/// the \c msg error message. By using
5.625 +/// LEMON_ASSERT_EXCEPTION, one can define an arbitrary exception to be thrown.
5.626 +///
5.627 +/// The LEMON_ASSERT macro should be called with the \c exp parameter
5.628 +/// which should be an expression convertible to bool. If the given
5.629 +/// parameter is false the assertion is raised and one of the assertion
5.630 +/// behaviour will be activated. The \c msg should be either a const
5.631 +/// char* message or an exception. When the \c msg is an exception the
5.632 +/// \ref lemon::Exception::what() "what()" function is called to retrieve and
5.633 +/// display the error message.
5.634 +///
5.635 +/// \todo We should provide some way to reset to the default behaviour,
5.636 +/// shouldn't we?
5.637 +///
5.638 +/// \todo This whole 'assert' business should be placed in a separate
5.639 +/// include file. The boost assert is not guarded by header sentries
5.640 +/// which may help to change the behaviour of the assertions in
5.641 +/// the files.
5.642 +///
5.643 +/// \todo __PRETTY_FUNCTION__ should be replaced by something
5.644 +/// compiler-independent, like BOOST_CURRENT_FUNCTION
5.645 +
5.646 +# define LEMON_ASSERT(exp, msg) \
5.647 + (static_cast<void> (!!(exp) ? 0 : ( \
5.648 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
5.649 + __PRETTY_FUNCTION__, \
5.650 + msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
5.651 +
5.652 +#else
5.653 +# if defined LEMON_DISABLE_ASSERTS
5.654 +
5.655 +# define LEMON_ASSERT(exp, msg) (static_cast<void> (0))
5.656 +
5.657 +# else
5.658 +# define LEMON_ASSERT(exp, msg) \
5.659 + (static_cast<void> (!!(exp) ? 0 : ( \
5.660 + LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \
5.661 + __PRETTY_FUNCTION__, \
5.662 + msg, #exp, LEMON_ASSERT_DO_ABORT), 0)))
5.663 +# endif
5.664 +#endif
5.665 +
5.666 +/**
5.667 + * \brief Macro for mark not yet implemented features.
5.668 + *
5.669 + * \todo Is this the right place for this? It should be used only in
5.670 + * modules under development.
5.671 + *
5.672 + * \todo __PRETTY_FUNCTION__ should be replaced by something
5.673 + * compiler-independent, like BOOST_CURRENT_FUNCTION
5.674 + */
5.675 +
5.676 +#define LEMON_FIXME(msg) \
5.677 + (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
5.678 + "FIXME: " msg))
6.1 --- a/lemon/random.h Thu Jan 24 17:36:45 2008 +0000
6.2 +++ b/lemon/random.h Thu Feb 07 21:28:39 2008 +0000
6.3 @@ -254,7 +254,7 @@
6.4 curr[length - shift] ^ mask[curr[-1] & 1ul];
6.5 --curr;
6.6 }
6.7 - curr[0] = (((curr[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
6.8 + state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
6.9 curr[length - shift] ^ mask[curr[length - 1] & 1ul];
6.10
6.11 }
7.1 --- a/test/Makefile.am Thu Jan 24 17:36:45 2008 +0000
7.2 +++ b/test/Makefile.am Thu Feb 07 21:28:39 2008 +0000
7.3 @@ -10,6 +10,7 @@
7.4 test/digraph_test \
7.5 test/dim_test \
7.6 test/graph_test \
7.7 + test/maps_test \
7.8 test/random_test \
7.9 test/path_test \
7.10 test/test_tools_fail \
7.11 @@ -20,7 +21,9 @@
7.12
7.13 test_digraph_test_SOURCES = test/digraph_test.cc
7.14 test_dim_test_SOURCES = test/dim_test.cc
7.15 +#test_error_test_SOURCES = test/error_test.cc
7.16 test_graph_test_SOURCES = test/graph_test.cc
7.17 +test_maps_test_SOURCES = test/maps_test.cc
7.18 test_path_test_SOURCES = test/path_test.cc
7.19 test_random_test_SOURCES = test/random_test.cc
7.20 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/test/error_test.cc Thu Feb 07 21:28:39 2008 +0000
8.3 @@ -0,0 +1,68 @@
8.4 +/* -*- C++ -*-
8.5 + *
8.6 + * This file is a part of LEMON, a generic C++ optimization library
8.7 + *
8.8 + * Copyright (C) 2003-2008
8.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
8.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
8.11 + *
8.12 + * Permission to use, modify and distribute this software is granted
8.13 + * provided that this copyright notice appears in all copies. For
8.14 + * precise terms see the accompanying LICENSE file.
8.15 + *
8.16 + * This software is provided "AS IS" with no warranty of any kind,
8.17 + * express or implied, and with no claim as to its suitability for any
8.18 + * purpose.
8.19 + *
8.20 + */
8.21 +
8.22 +#include <iostream>
8.23 +
8.24 +#include <lemon/error.h>
8.25 +#include "test_tools.h"
8.26 +
8.27 +using namespace lemon;
8.28 +using std::cout;
8.29 +using std::endl;
8.30 +
8.31 +void faulty_fn() {
8.32 + fault("This is a fault message");
8.33 +}
8.34 +
8.35 +void exception_fn() {
8.36 + throw Exception("This is a function throwing exception with some args: ")
8.37 + << 5 << ", " << 18;
8.38 +}
8.39 +
8.40 +void unfinished_fn() {
8.41 + LEMON_FIXME("unfinished_fn() is unfinished!");
8.42 +}
8.43 +
8.44 +
8.45 +int main() {
8.46 + try {
8.47 + faulty_fn();
8.48 + check(false, "A faulty function did not fail.");
8.49 + }
8.50 + catch(const Exception &e) {
8.51 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
8.52 + }
8.53 +
8.54 + try {
8.55 + exception_fn();
8.56 + check(false, "The function did not throw Exception.");
8.57 + }
8.58 + catch(const Exception &e) {
8.59 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
8.60 + }
8.61 +
8.62 + try {
8.63 + unfinished_fn();
8.64 + check(false, "FIXME macro does not work.");
8.65 + }
8.66 + catch(const Exception &e) {
8.67 + cout << "Exeption = \"" << e.what() << "\" (Right behaviour)" << endl;
8.68 + }
8.69 +
8.70 + return 0;
8.71 +}