Merge
authorAlpar Juttner <alpar@cs.elte.hu>
Thu, 07 Feb 2008 21:28:39 +0000
changeset 99dbaa96cc1013
parent 98 c4582fc14f58
parent 67 9de02aa380de
child 100 4f754b4cf82b
Merge
lemon/Makefile.am
test/Makefile.am
     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 +}