Merge
authorAlpar Juttner <alpar@cs.elte.hu>
Sat, 12 Apr 2008 20:38:51 +0100
changeset 124ae7785fe8431
parent 123 8899d1891a3c
parent 122 35840c5aa696
child 125 19e82bda606a
Merge
     1.1 --- a/lemon/Makefile.am	Tue Apr 08 22:51:26 2008 +0200
     1.2 +++ b/lemon/Makefile.am	Sat Apr 12 20:38:51 2008 +0100
     1.3 @@ -20,6 +20,7 @@
     1.4  	lemon/assert.h \
     1.5          lemon/bfs.h \
     1.6          lemon/bin_heap.h \
     1.7 +        lemon/counter.h \
     1.8          lemon/dfs.h \
     1.9          lemon/dijkstra.h \
    1.10          lemon/dim2.h \
    1.11 @@ -32,6 +33,7 @@
    1.12  	lemon/path.h \
    1.13          lemon/random.h \
    1.14  	lemon/smart_graph.h \
    1.15 +        lemon/time_measure.h \
    1.16          lemon/tolerance.h \
    1.17  	lemon/unionfind.h
    1.18  
     2.1 --- a/lemon/assert.h	Tue Apr 08 22:51:26 2008 +0200
     2.2 +++ b/lemon/assert.h	Sat Apr 12 20:38:51 2008 +0100
     2.3 @@ -27,71 +27,6 @@
     2.4  
     2.5  namespace lemon {
     2.6  
     2.7 -  /// @{
     2.8 -
     2.9 -  ///\e
    2.10 -  class AssertionFailedError : public LogicError {
    2.11 -  protected:
    2.12 -    const char *_assertion;
    2.13 -    const char *_file;
    2.14 -    int _line;
    2.15 -    const char *_function;
    2.16 -    const char *_message;
    2.17 -
    2.18 -    mutable ExceptionMember<std::string> _message_holder;
    2.19 -  public:
    2.20 -    ///\e
    2.21 -    AssertionFailedError(const char *file, int line, const char *function,
    2.22 -			 const char *msg, const char *assertion = 0) :
    2.23 -      _assertion(assertion), _file(file), _line(line), 
    2.24 -      _function(function), _message(msg) {}
    2.25 -
    2.26 -    ///\e
    2.27 -    const char* assertion() const { return _assertion; }
    2.28 -    ///\e
    2.29 -    const char* message() const { return _message; }
    2.30 -    ///\e
    2.31 -    const char* file() const { return _file; }
    2.32 -    ///\e
    2.33 -    const char* function() const { return _function; }
    2.34 -    ///\e
    2.35 -    int line() const { return _line; }
    2.36 -
    2.37 -
    2.38 -    virtual const char* what() const throw() {
    2.39 -      try {
    2.40 -	std::ostringstream ostr;
    2.41 -	ostr << _file << ":" << _line << ": ";
    2.42 -	if (_function)
    2.43 -	  ostr << _function << ": ";
    2.44 -	ostr << _message;
    2.45 -	if (_assertion)
    2.46 -	   ostr << " (assertion '" << _assertion << "' failed)";
    2.47 -	_message_holder.set(ostr.str());
    2.48 -	return ostr.str().c_str();
    2.49 -      }
    2.50 -      catch(...) {}
    2.51 -      if( _message_holder.valid() ) return _message_holder.get().c_str();
    2.52 -      return "lemon::AssertionFailedError";
    2.53 -    }
    2.54 -    virtual ~AssertionFailedError() throw() {}
    2.55 -  };
    2.56 -
    2.57 -
    2.58 -  inline void assert_fail_log(const char *file, int line,
    2.59 -			      const char *function,
    2.60 -			      const std::exception& exception, 
    2.61 -			      const char *assertion)
    2.62 -  {
    2.63 -    std::cerr << file << ":" << line << ": ";
    2.64 -    if (function)
    2.65 -      std::cerr << function << ": ";
    2.66 -    std::cerr << exception.what();
    2.67 -    if (assertion)
    2.68 -      std::cerr << " (assertion '" << assertion << "' failed)";
    2.69 -    std::cerr << std::endl;
    2.70 -  }
    2.71 -
    2.72    inline void assert_fail_log(const char *file, int line, const char *function,
    2.73  			      const char *message, const char *assertion)
    2.74    {
    2.75 @@ -104,21 +39,6 @@
    2.76      std::cerr << std::endl;
    2.77    }
    2.78  
    2.79 -  inline void assert_fail_log(const char *file, int line, const char *function, 
    2.80 -			      const std::string& message, const char *assertion)
    2.81 -  {
    2.82 -    assert_fail_log(file, line, function, message.c_str(), assertion);
    2.83 -  }
    2.84 -
    2.85 -  inline void assert_fail_abort(const char *file, int line, 
    2.86 -				const char *function,
    2.87 -				const std::exception& exception,
    2.88 -				const char *assertion)
    2.89 -  {
    2.90 -    assert_fail_log(file, line, function, exception, assertion);
    2.91 -    std::abort();
    2.92 -  }
    2.93 -
    2.94    inline void assert_fail_abort(const char *file, int line,
    2.95  				const char *function, const char* message,
    2.96  				const char *assertion)
    2.97 @@ -127,86 +47,37 @@
    2.98      std::abort();
    2.99    }
   2.100  
   2.101 -  inline void assert_fail_abort(const char *file, int line, 
   2.102 -				const char *function, 
   2.103 -				const std::string& message,
   2.104 -				const char *assertion)
   2.105 -  {
   2.106 -    assert_fail_log(file, line, function, message.c_str(), assertion);
   2.107 -    std::abort();
   2.108 +  namespace _assert_bits {
   2.109 +    
   2.110 +    
   2.111 +    inline const char* cstringify(const std::string& str) {
   2.112 +      return str.c_str();
   2.113 +    }
   2.114 +
   2.115 +    inline const char* cstringify(const char* str) {
   2.116 +      return str;
   2.117 +    }    
   2.118    }
   2.119 +}
   2.120  
   2.121 -  inline void assert_fail_error(const char *file, int line, 
   2.122 -				  const char *function,
   2.123 -				  const std::exception& exception,
   2.124 -				  const char *assertion)
   2.125 -  {
   2.126 -    throw AssertionFailedError(file, line, function, 
   2.127 -			       exception.what(), assertion);
   2.128 -  }
   2.129 -
   2.130 -  inline void assert_fail_error(const char *file, int line,
   2.131 -				  const char *function, const char *message,
   2.132 -				  const char *assertion)
   2.133 -  {
   2.134 -    throw AssertionFailedError(file, line, function, message, assertion);
   2.135 -  }
   2.136 -
   2.137 -  inline void assert_fail_error(const char *file, int line,
   2.138 -				  const char *function, 
   2.139 -				  const std::string& message,
   2.140 -				  const char *assertion)
   2.141 -  {
   2.142 -    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
   2.143 -  }
   2.144 -
   2.145 -  template <typename Exception>
   2.146 -  inline void assert_fail_exception(const char *, int, const char *,
   2.147 -				    const Exception& exception,
   2.148 -				    const char *, const std::exception* = 
   2.149 -				    static_cast<const Exception*>(0))
   2.150 -  {
   2.151 -    throw exception;
   2.152 -  }
   2.153 -
   2.154 -  inline void assert_fail_exception(const char *file, int line,
   2.155 -				    const char *function, const char *message,
   2.156 -				    const char *assertion)
   2.157 -  {
   2.158 -    throw AssertionFailedError(file, line, function, message, assertion);
   2.159 -  }
   2.160 -
   2.161 -  inline void assert_fail_exception(const char *file, int line, 
   2.162 -				    const char *function, 
   2.163 -				    const std::string& message,
   2.164 -				    const char *assertion)
   2.165 -  {
   2.166 -    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
   2.167 -  }
   2.168 -
   2.169 -/// @}
   2.170 -
   2.171 -}
   2.172  #endif // LEMON_ASSERT_H
   2.173  
   2.174  #undef LEMON_ASSERT
   2.175  #undef LEMON_FIXME
   2.176 +#undef LEMON_DEBUG
   2.177  
   2.178  #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
   2.179    (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
   2.180 -  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
   2.181 -  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
   2.182    (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
   2.183  #error "LEMON assertion system is not set properly"
   2.184  #endif
   2.185  
   2.186  #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
   2.187       (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
   2.188 -     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
   2.189 -     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
   2.190       (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
   2.191       defined(LEMON_ENABLE_ASSERTS)) &&			\
   2.192 -  defined(LEMON_DISABLE_ASSERTS)
   2.193 +  (defined(LEMON_DISABLE_ASSERTS) ||			\
   2.194 +   defined(NDEBUG))
   2.195  #error "LEMON assertion system is not set properly"
   2.196  #endif
   2.197  
   2.198 @@ -217,26 +88,20 @@
   2.199  #elif defined LEMON_ASSERT_ABORT
   2.200  #  undef LEMON_ASSERT_HANDLER
   2.201  #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
   2.202 -#elif defined LEMON_ASSERT_ERROR
   2.203 -#  undef LEMON_ASSERT_HANDLER
   2.204 -#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
   2.205 -#elif defined LEMON_ASSERT_EXCEPTION
   2.206 -#  undef LEMON_ASSERT_HANDLER
   2.207 -#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
   2.208  #elif defined LEMON_ASSERT_CUSTOM
   2.209  #  undef LEMON_ASSERT_HANDLER
   2.210  #  ifndef LEMON_CUSTOM_ASSERT_HANDLER
   2.211  #    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
   2.212  #  endif
   2.213  #  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
   2.214 -#elif defined LEMON_ENABLE_ASSERTS
   2.215 +#elif defined LEMON_DISABLE_ASSERTS
   2.216  #  undef LEMON_ASSERT_HANDLER
   2.217 +#elif defined NDEBUG
   2.218 +#  undef LEMON_ASSERT_HANDLER
   2.219 +#else
   2.220  #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
   2.221 -#else
   2.222 -#  undef LEMON_ASSERT_HANDLER
   2.223  #endif
   2.224  
   2.225 -
   2.226  #ifndef LEMON_FUNCTION_NAME
   2.227  #  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
   2.228  #endif
   2.229 @@ -247,24 +112,24 @@
   2.230  ///
   2.231  /// \brief Macro for assertion with customizable message
   2.232  ///
   2.233 -/// Macro for assertion with customizable message.  
   2.234 -/// \param exp An expression that must be convertible to \c bool.
   2.235 -/// If it is \c false, then an assertion is raised. The concrete
   2.236 -/// behaviour depends on the settings of the assertion system.
   2.237 -/// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
   2.238 -/// a <tt>const std::exception&</tt> parameter, which can be used to
   2.239 -/// provide information about the circumstances of the failed assertion.
   2.240 +/// Macro for assertion with customizable message.  \param exp An
   2.241 +/// expression that must be convertible to \c bool.  If it is \c
   2.242 +/// false, then an assertion is raised. The concrete behaviour depends
   2.243 +/// on the settings of the assertion system.  \param msg A <tt>const
   2.244 +/// char*</tt> parameter, which can be used to provide information
   2.245 +/// about the circumstances of the failed assertion.
   2.246  ///
   2.247 -/// The assertions are disabled in the default behaviour.
   2.248 -/// You can enable them with the following code:
   2.249 +/// The assertions are enabled in the default behaviour.
   2.250 +/// You can disable them with the following code:
   2.251  /// \code
   2.252 -/// #define LEMON_ENABLE_ASSERTS
   2.253 +/// #define LEMON_DISABLE_ASSERTS
   2.254  /// \endcode
   2.255  /// or with compilation parameters:
   2.256  /// \code
   2.257 -/// g++ -DLEMON_ENABLE_ASSERTS
   2.258 -/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
   2.259 +/// g++ -DLEMON_DISABLE_ASSERTS
   2.260 +/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
   2.261  /// \endcode
   2.262 +/// The checking is also disabled when the standard macro \c NDEBUG is defined.
   2.263  /// 
   2.264  /// The LEMON assertion system has a wide range of customization
   2.265  /// properties. As a default behaviour the failed assertion prints a
   2.266 @@ -274,38 +139,22 @@
   2.267  ///
   2.268  /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
   2.269  ///   message to the standard error and continues the execution.
   2.270 -/// - \c LEMON_ASSERT_ABORT This mode is similar to the
   2.271 -///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
   2.272 -///   behaviour mode when the assertions are enabled with
   2.273 -///   \c LEMON_ENABLE_ASSERTS.
   2.274 -/// - \c LEMON_ASSERT_ERROR The assertion throws an
   2.275 -///   \ref lemon::AssertionFailedError "AssertionFailedError".
   2.276 -///   If the \c msg parameter is an exception, then the result of the
   2.277 -///   \ref lemon::Exception::what() "what()" member function is passed
   2.278 -///   as error message.
   2.279 -/// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
   2.280 -///   exception, then it raised directly (solving that the exception
   2.281 -///   can not be thrown polymorphically), otherwise an \ref
   2.282 -///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
   2.283 -///   the given parameters.
   2.284 +/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
   2.285 +///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
   2.286 +///   behaviour.
   2.287  /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
   2.288 -///   functions. Three overloaded functions should be defined with the
   2.289 -///   following parameter lists:
   2.290 +///   function.
   2.291  ///   \code
   2.292  ///     void custom_assert_handler(const char* file, int line, const char* function,
   2.293  ///                                const char* message, const char* assertion);
   2.294 -///     void custom_assert_handler(const char* file, int line, const char* function,
   2.295 -///                                const std::string& message, const char* assertion);
   2.296 -///     void custom_assert_handler(const char* file, int line, const char* function,
   2.297 -///                                const std::exception& message, const char* assertion);
   2.298  ///   \endcode
   2.299 -///   The name of the functions should be defined as the \c
   2.300 +///   The name of the function should be defined as the \c
   2.301  ///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
   2.302  ///   \code
   2.303  ///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
   2.304  ///   \endcode
   2.305 -///   Whenever an assertion is occured, one of the custom assertion
   2.306 -///   handlers is called with appropiate parameters.
   2.307 +///   Whenever an assertion is occured, the custom assertion
   2.308 +///   handler is called with appropiate parameters.
   2.309  ///
   2.310  /// The assertion mode can also be changed within one compilation unit.
   2.311  /// If the macros are redefined with other settings and the
   2.312 @@ -315,8 +164,7 @@
   2.313    (static_cast<void> (!!(exp) ? 0 : (					\
   2.314      LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
   2.315  			 LEMON_FUNCTION_NAME,				\
   2.316 -			 msg, #exp), 0)))
   2.317 -
   2.318 +			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
   2.319  
   2.320  /// \ingroup exceptions
   2.321  ///
   2.322 @@ -327,26 +175,80 @@
   2.323  /// \code
   2.324  ///   LEMON_ASSERT(false, msg);
   2.325  /// \endcode
   2.326 +///
   2.327 +/// \see LEMON_ASSERT 
   2.328  #  define LEMON_FIXME(msg)						\
   2.329 -       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
   2.330 -			     "FIXME: " msg, static_cast<const char*>(0)))
   2.331 +  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
   2.332 +			::lemon::_assert_bits::cstringify(msg),		\
   2.333 +			static_cast<const char*>(0)))
   2.334 +
   2.335 +/// \ingroup exceptions
   2.336 +///
   2.337 +/// \brief Macro for internal assertions
   2.338 +///
   2.339 +/// Macro for internal assertions, it is used in the library to check
   2.340 +/// the consistency of results of algorithms, several pre- and
   2.341 +/// postconditions and invariants. The checking is disabled by
   2.342 +/// default, but it can be turned on with the macro \c
   2.343 +/// LEMON_ENABLE_DEBUG.
   2.344 +/// \code
   2.345 +/// #define LEMON_ENABLE_DEBUG
   2.346 +/// \endcode
   2.347 +/// or with compilation parameters:
   2.348 +/// \code
   2.349 +/// g++ -DLEMON_ENABLE_DEBUG
   2.350 +/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
   2.351 +/// \endcode
   2.352 +///
   2.353 +/// This macro works like the \c LEMON_ASSERT macro, therefore the
   2.354 +/// current behaviour depends on the settings of \c LEMON_ASSERT
   2.355 +/// macro.
   2.356 +///
   2.357 +/// \see LEMON_ASSERT 
   2.358 +#  define LEMON_DEBUG(exp, msg)						\
   2.359 +  (static_cast<void> (!!(exp) ? 0 : (					\
   2.360 +    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
   2.361 +			 LEMON_FUNCTION_NAME,				\
   2.362 +			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
   2.363  
   2.364  #else
   2.365  
   2.366  #  ifndef LEMON_ASSERT_HANDLER
   2.367  #    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
   2.368  #    define LEMON_FIXME(msg) (static_cast<void>(0))
   2.369 +#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
   2.370  #  else
   2.371 -#    define LEMON_ASSERT(exp, msg)                 \
   2.372 -       (static_cast<void> (!!(exp) ? 0 : (         \
   2.373 -         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
   2.374 -                              LEMON_FUNCTION_NAME, \
   2.375 -                              msg, #exp), 0)))
   2.376 -#    define LEMON_FIXME(msg) \
   2.377 +#    define LEMON_ASSERT(exp, msg)					\
   2.378 +       (static_cast<void> (!!(exp) ? 0 : (				\
   2.379 +        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
   2.380 +			     LEMON_FUNCTION_NAME,			\
   2.381 +			     ::lemon::_assert_bits::cstringify(msg),	\
   2.382 +			     #exp), 0)))
   2.383 +#    define LEMON_FIXME(msg)						\
   2.384         (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
   2.385 -			     "FIXME: " msg,  static_cast<const char*>(0)))
   2.386 +			     ::lemon::_assert_bits::cstringify(msg),	\
   2.387 +			     static_cast<const char*>(0)))
   2.388 +
   2.389 +#    if LEMON_ENABLE_DEBUG
   2.390 +#      define LEMON_DEBUG(exp, msg)
   2.391 +         (static_cast<void> (!!(exp) ? 0 : (         \
   2.392 +           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
   2.393 +                                LEMON_FUNCTION_NAME, \
   2.394 +				::lemon::_assert_bits::cstringify(msg),	\
   2.395 +				#exp), 0)))
   2.396 +#    else
   2.397 +#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
   2.398 +#    endif
   2.399  #  endif
   2.400  
   2.401  #endif
   2.402  
   2.403 +#ifdef DOXYGEN
   2.404  
   2.405 +
   2.406 +#else
   2.407 +
   2.408 +
   2.409 +#endif
   2.410 +
   2.411 +
     3.1 --- a/lemon/bits/utility.h	Tue Apr 08 22:51:26 2008 +0200
     3.2 +++ b/lemon/bits/utility.h	Sat Apr 12 20:38:51 2008 +0100
     3.3 @@ -21,13 +21,13 @@
     3.4  
     3.5  // Boost enable_if library
     3.6  
     3.7 -// Copyright 2003 © The Trustees of Indiana University.
     3.8 +// Copyright 2003 (c) The Trustees of Indiana University.
     3.9  
    3.10  // Use, modification, and distribution is subject to the Boost Software
    3.11  // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    3.12  // http://www.boost.org/LICENSE_1_0.txt)
    3.13  
    3.14 -//    Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
    3.15 +//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
    3.16  //             Jeremiah Willcock (jewillco at osl.iu.edu)
    3.17  //             Andrew Lumsdaine (lums at osl.iu.edu)
    3.18  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/lemon/counter.h	Sat Apr 12 20:38:51 2008 +0100
     4.3 @@ -0,0 +1,181 @@
     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 +#ifndef LEMON_COUNTER_H
    4.23 +#define LEMON_COUNTER_H
    4.24 +
    4.25 +#include <string>
    4.26 +#include <iostream>
    4.27 +
    4.28 +///\ingroup timecount
    4.29 +///\file
    4.30 +///\brief Tools for counting steps and events
    4.31 +
    4.32 +namespace lemon 
    4.33 +{
    4.34 +
    4.35 +  template<class P> class _NoSubCounter;
    4.36 +
    4.37 +  template<class P>
    4.38 +  class _SubCounter 
    4.39 +  {
    4.40 +    P &_parent;
    4.41 +    std::string _title;
    4.42 +    std::ostream &_os;
    4.43 +    int count;
    4.44 +  public:
    4.45 +
    4.46 +    typedef _SubCounter<_SubCounter<P> > SubCounter;
    4.47 +    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
    4.48 +
    4.49 +    _SubCounter(P &parent)
    4.50 +      : _parent(parent), _title(), _os(std::cerr), count(0) {}
    4.51 +    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
    4.52 +      : _parent(parent), _title(title), _os(os), count(0) {}
    4.53 +    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
    4.54 +      : _parent(parent), _title(title), _os(os), count(0) {}
    4.55 +    ~_SubCounter() { 
    4.56 +      _os << _title << count <<std::endl;
    4.57 +      _parent+=count;
    4.58 +    }
    4.59 +    _SubCounter &operator++() { count++; return *this;}
    4.60 +    int operator++(int) { return count++; }
    4.61 +    _SubCounter &operator--() { count--; return *this;}
    4.62 +    int operator--(int) { return count--; }
    4.63 +    _SubCounter &operator+=(int c) { count+=c; return *this;}
    4.64 +    _SubCounter &operator-=(int c) { count-=c; return *this;}
    4.65 +    void reset(int c=0) {count=c;}
    4.66 +    operator int() {return count;}
    4.67 +  };
    4.68 +
    4.69 +  template<class P>
    4.70 +  class _NoSubCounter 
    4.71 +  {
    4.72 +    P &_parent;
    4.73 +  public:
    4.74 +    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
    4.75 +    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
    4.76 +  
    4.77 +    _NoSubCounter(P &parent) :_parent(parent) {}
    4.78 +    _NoSubCounter(P &parent,std::string,std::ostream &) 
    4.79 +      :_parent(parent) {}
    4.80 +    _NoSubCounter(P &parent,std::string) 
    4.81 +      :_parent(parent) {}
    4.82 +    _NoSubCounter(P &parent,const char *,std::ostream &)
    4.83 +      :_parent(parent) {}
    4.84 +    _NoSubCounter(P &parent,const char *)
    4.85 +      :_parent(parent) {}
    4.86 +    ~_NoSubCounter() {}
    4.87 +    _NoSubCounter &operator++() { ++_parent; return *this;}
    4.88 +    int operator++(int) { _parent++; return 0;}
    4.89 +    _NoSubCounter &operator--() { --_parent; return *this;}
    4.90 +    int operator--(int) { _parent--; return 0;}
    4.91 +    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
    4.92 +    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
    4.93 +    void reset(int) {}
    4.94 +    void reset() {}
    4.95 +    operator int() {return 0;}
    4.96 +  };
    4.97 +
    4.98 +
    4.99 +  /// \addtogroup timecount
   4.100 +  /// @{
   4.101 +
   4.102 +  ///A counter class
   4.103 +
   4.104 +  ///This class makes it easier to count certain events. You can increment
   4.105 +  ///or decrement the counter using operator++ and operator--.
   4.106 +  ///A report is automatically printed on destruction.
   4.107 +  ///\todo More doc
   4.108 +  class Counter 
   4.109 +  {
   4.110 +    std::string _title;
   4.111 +    std::ostream &_os;
   4.112 +    int count;
   4.113 +  public:
   4.114 +    ///\e
   4.115 +
   4.116 +    ///\todo document please.
   4.117 +    ///
   4.118 +    typedef _SubCounter<Counter> SubCounter;
   4.119 +    ///\e
   4.120 +
   4.121 +    ///\todo document please.
   4.122 +    ///
   4.123 +    typedef _NoSubCounter<Counter> NoSubCounter;
   4.124 +
   4.125 +    ///\e
   4.126 +    Counter() : _title(), _os(std::cerr), count(0) {}
   4.127 +    ///\e
   4.128 +    Counter(std::string title,std::ostream &os=std::cerr) 
   4.129 +      : _title(title), _os(os), count(0) {}
   4.130 +    ///\e
   4.131 +    Counter(const char *title,std::ostream &os=std::cerr)
   4.132 +      : _title(title), _os(os), count(0) {}
   4.133 +    ///Destructor. Prints the given title and the value of the counter.
   4.134 +    ~Counter() {
   4.135 +      _os << _title << count <<std::endl;
   4.136 +    }
   4.137 +    ///\e
   4.138 +    Counter &operator++() { count++; return *this;}
   4.139 +    ///\e
   4.140 +    int operator++(int) { return count++;}
   4.141 +    ///\e
   4.142 +    Counter &operator--() { count--; return *this;}
   4.143 +    ///\e
   4.144 +    int operator--(int) { return count--;}
   4.145 +    ///\e
   4.146 +    Counter &operator+=(int c) { count+=c; return *this;}
   4.147 +    ///\e
   4.148 +    Counter &operator-=(int c) { count-=c; return *this;}
   4.149 +    ///\e
   4.150 +    void reset(int c=0) {count=c;}
   4.151 +    ///\e
   4.152 +    operator int() {return count;}
   4.153 +  };
   4.154 +
   4.155 +  ///'Do nothing' version of \ref Counter
   4.156 +
   4.157 +  ///'Do nothing' version of \ref Counter.
   4.158 +  ///\sa Counter
   4.159 +  class NoCounter
   4.160 +  {
   4.161 +  public:
   4.162 +    typedef _NoSubCounter<NoCounter> SubCounter;
   4.163 +    typedef _NoSubCounter<NoCounter> NoSubCounter;
   4.164 +
   4.165 +    NoCounter() {}
   4.166 +    NoCounter(std::string,std::ostream &) {}
   4.167 +    NoCounter(const char *,std::ostream &) {}
   4.168 +    NoCounter(std::string) {}
   4.169 +    NoCounter(const char *) {}
   4.170 +    NoCounter &operator++() { return *this; }
   4.171 +    int operator++(int) { return 0; }
   4.172 +    NoCounter &operator--() { return *this; }
   4.173 +    int operator--(int) { return 0; }
   4.174 +    NoCounter &operator+=(int) { return *this;}
   4.175 +    NoCounter &operator-=(int) { return *this;}
   4.176 +    void reset(int) {}
   4.177 +    void reset() {}
   4.178 +    operator int() {return 0;}
   4.179 +  };
   4.180 +
   4.181 +  ///@}
   4.182 +}
   4.183 +
   4.184 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/lemon/time_measure.h	Sat Apr 12 20:38:51 2008 +0100
     5.3 @@ -0,0 +1,541 @@
     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_TIME_MEASURE_H
    5.23 +#define LEMON_TIME_MEASURE_H
    5.24 +
    5.25 +///\ingroup timecount
    5.26 +///\file
    5.27 +///\brief Tools for measuring cpu usage
    5.28 +
    5.29 +#include <sys/times.h>
    5.30 +
    5.31 +#include <sys/time.h>
    5.32 +#include <fstream>
    5.33 +#include <iostream>
    5.34 +#include <unistd.h>
    5.35 +
    5.36 +namespace lemon {
    5.37 +
    5.38 +  /// \addtogroup timecount
    5.39 +  /// @{
    5.40 +
    5.41 +  /// A class to store (cpu)time instances.
    5.42 +
    5.43 +  /// This class stores five time values.
    5.44 +  /// - a real time
    5.45 +  /// - a user cpu time
    5.46 +  /// - a system cpu time
    5.47 +  /// - a user cpu time of children
    5.48 +  /// - a system cpu time of children
    5.49 +  ///
    5.50 +  /// TimeStamp's can be added to or substracted from each other and
    5.51 +  /// they can be pushed to a stream.
    5.52 +  ///
    5.53 +  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
    5.54 +  /// class is what you want to use instead.
    5.55 +  ///
    5.56 +  ///\author Alpar Juttner
    5.57 +
    5.58 +  class TimeStamp
    5.59 +  {
    5.60 +    struct rtms 
    5.61 +    {
    5.62 +      double tms_utime;
    5.63 +      double tms_stime;
    5.64 +      double tms_cutime;
    5.65 +      double tms_cstime;
    5.66 +      rtms() {}
    5.67 +      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
    5.68 +		     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
    5.69 +    };
    5.70 +    rtms ts;
    5.71 +    double real_time;
    5.72 +  
    5.73 +    rtms &getTms() {return ts;}
    5.74 +    const rtms &getTms() const {return ts;}
    5.75 +
    5.76 +    void _reset() { 
    5.77 +      ts.tms_utime = ts.tms_stime = ts.tms_cutime = ts.tms_cstime = 0; 
    5.78 +      real_time = 0;
    5.79 +    }
    5.80 +
    5.81 +  public:
    5.82 +
    5.83 +    ///Read the current time values of the process
    5.84 +    void stamp()
    5.85 +    {
    5.86 +      timeval tv;
    5.87 +      tms _ts;
    5.88 +      times(&_ts);
    5.89 +      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
    5.90 +      ts=_ts;
    5.91 +    }
    5.92 +  
    5.93 +    /// Constructor initializing with zero
    5.94 +    TimeStamp()
    5.95 +    { _reset(); }
    5.96 +    ///Constructor initializing with the current time values of the process
    5.97 +    TimeStamp(void *) { stamp();}
    5.98 +  
    5.99 +    ///Set every time value to zero
   5.100 +    TimeStamp &reset() {_reset();return *this;}
   5.101 +
   5.102 +    ///\e
   5.103 +    TimeStamp &operator+=(const TimeStamp &b)
   5.104 +    {
   5.105 +      ts.tms_utime+=b.ts.tms_utime;
   5.106 +      ts.tms_stime+=b.ts.tms_stime;
   5.107 +      ts.tms_cutime+=b.ts.tms_cutime;
   5.108 +      ts.tms_cstime+=b.ts.tms_cstime;
   5.109 +      real_time+=b.real_time;
   5.110 +      return *this;
   5.111 +    }
   5.112 +    ///\e
   5.113 +    TimeStamp operator+(const TimeStamp &b) const
   5.114 +    {
   5.115 +      TimeStamp t(*this);
   5.116 +      return t+=b;
   5.117 +    }
   5.118 +    ///\e
   5.119 +    TimeStamp &operator-=(const TimeStamp &b)
   5.120 +    {
   5.121 +      ts.tms_utime-=b.ts.tms_utime;
   5.122 +      ts.tms_stime-=b.ts.tms_stime;
   5.123 +      ts.tms_cutime-=b.ts.tms_cutime;
   5.124 +      ts.tms_cstime-=b.ts.tms_cstime;
   5.125 +      real_time-=b.real_time;
   5.126 +      return *this;
   5.127 +    }
   5.128 +    ///\e
   5.129 +    TimeStamp operator-(const TimeStamp &b) const
   5.130 +    {
   5.131 +      TimeStamp t(*this);
   5.132 +      return t-=b;
   5.133 +    }
   5.134 +    ///\e
   5.135 +    TimeStamp &operator*=(double b)
   5.136 +    {
   5.137 +      ts.tms_utime*=b;
   5.138 +      ts.tms_stime*=b;
   5.139 +      ts.tms_cutime*=b;
   5.140 +      ts.tms_cstime*=b;
   5.141 +      real_time*=b;
   5.142 +      return *this;
   5.143 +    }
   5.144 +    ///\e
   5.145 +    TimeStamp operator*(double b) const
   5.146 +    {
   5.147 +      TimeStamp t(*this);
   5.148 +      return t*=b;
   5.149 +    }
   5.150 +    friend TimeStamp operator*(double b,const TimeStamp &t);
   5.151 +    ///\e
   5.152 +    TimeStamp &operator/=(double b)
   5.153 +    {
   5.154 +      ts.tms_utime/=b;
   5.155 +      ts.tms_stime/=b;
   5.156 +      ts.tms_cutime/=b;
   5.157 +      ts.tms_cstime/=b;
   5.158 +      real_time/=b;
   5.159 +      return *this;
   5.160 +    }
   5.161 +    ///\e
   5.162 +    TimeStamp operator/(double b) const
   5.163 +    {
   5.164 +      TimeStamp t(*this);
   5.165 +      return t/=b;
   5.166 +    }
   5.167 +    ///The time ellapsed since the last call of stamp()
   5.168 +    TimeStamp ellapsed() const
   5.169 +    {
   5.170 +      TimeStamp t(NULL);
   5.171 +      return t-*this;
   5.172 +    }
   5.173 +  
   5.174 +    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
   5.175 +  
   5.176 +    ///Gives back the user time of the process
   5.177 +    double userTime() const
   5.178 +    {
   5.179 +      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
   5.180 +    }
   5.181 +    ///Gives back the system time of the process
   5.182 +    double systemTime() const
   5.183 +    {
   5.184 +      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
   5.185 +    }
   5.186 +    ///Gives back the user time of the process' children
   5.187 +    double cUserTime() const
   5.188 +    {
   5.189 +      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
   5.190 +    }
   5.191 +    ///Gives back the user time of the process' children
   5.192 +    double cSystemTime() const
   5.193 +    {
   5.194 +      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
   5.195 +    }
   5.196 +    ///Gives back the real time
   5.197 +    double realTime() const {return real_time;}
   5.198 +  };
   5.199 +
   5.200 +  TimeStamp operator*(double b,const TimeStamp &t) 
   5.201 +  {
   5.202 +    return t*b;
   5.203 +  }
   5.204 +  
   5.205 +  ///Prints the time counters
   5.206 +
   5.207 +  ///Prints the time counters in the following form:
   5.208 +  ///
   5.209 +  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
   5.210 +  ///
   5.211 +  /// where the values are the
   5.212 +  /// \li \c u: user cpu time,
   5.213 +  /// \li \c s: system cpu time,
   5.214 +  /// \li \c cu: user cpu time of children,
   5.215 +  /// \li \c cs: system cpu time of children,
   5.216 +  /// \li \c real: real time.
   5.217 +  /// \relates TimeStamp
   5.218 +  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
   5.219 +  {
   5.220 +    long cls = sysconf(_SC_CLK_TCK);
   5.221 +    os << "u: " << double(t.getTms().tms_utime)/cls <<
   5.222 +      "s, s: " << double(t.getTms().tms_stime)/cls <<
   5.223 +      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
   5.224 +      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
   5.225 +      "s, real: " << t.realTime() << "s";
   5.226 +    return os;
   5.227 +  }
   5.228 +
   5.229 +  ///Class for measuring the cpu time and real time usage of the process
   5.230 +
   5.231 +  ///Class for measuring the cpu time and real time usage of the process.
   5.232 +  ///It is quite easy-to-use, here is a short example.
   5.233 +  ///\code
   5.234 +  /// #include<lemon/time_measure.h>
   5.235 +  /// #include<iostream>
   5.236 +  ///
   5.237 +  /// int main()
   5.238 +  /// {
   5.239 +  ///
   5.240 +  ///   ...
   5.241 +  ///
   5.242 +  ///   Timer t;
   5.243 +  ///   doSomething();
   5.244 +  ///   std::cout << t << '\n';
   5.245 +  ///   t.restart();
   5.246 +  ///   doSomethingElse();
   5.247 +  ///   std::cout << t << '\n';
   5.248 +  ///
   5.249 +  ///   ...
   5.250 +  ///
   5.251 +  /// }
   5.252 +  ///\endcode
   5.253 +  ///
   5.254 +  ///The \ref Timer can also be \ref stop() "stopped" and
   5.255 +  ///\ref start() "started" again, so it is possible to compute collected
   5.256 +  ///running times.
   5.257 +  ///
   5.258 +  ///\warning Depending on the operation system and its actual configuration
   5.259 +  ///the time counters have a certain (10ms on a typical Linux system)
   5.260 +  ///granularity.
   5.261 +  ///Therefore this tool is not appropriate to measure very short times.
   5.262 +  ///Also, if you start and stop the timer very frequently, it could lead to
   5.263 +  ///distorted results.
   5.264 +  ///
   5.265 +  ///\note If you want to measure the running time of the execution of a certain
   5.266 +  ///function, consider the usage of \ref TimeReport instead.
   5.267 +  ///
   5.268 +  ///\todo This shouldn't be Unix (Linux) specific.
   5.269 +  ///\sa TimeReport
   5.270 +  ///
   5.271 +  ///\author Alpar Juttner
   5.272 +  class Timer
   5.273 +  {
   5.274 +    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
   5.275 +    TimeStamp start_time; //This is the relativ start-time if the timer
   5.276 +                          //is _running, the collected _running time otherwise.
   5.277 +    
   5.278 +    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
   5.279 +  
   5.280 +  public: 
   5.281 +    ///Constructor.
   5.282 +
   5.283 +    ///\param run indicates whether or not the timer starts immediately.
   5.284 +    ///
   5.285 +    Timer(bool run=true) :_running(run) {_reset();}
   5.286 +
   5.287 +    ///\name Control the state of the timer
   5.288 +    ///Basically a Timer can be either running or stopped,
   5.289 +    ///but it provides a bit finer control on the execution.
   5.290 +    ///The \ref Timer also counts the number of \ref start()
   5.291 +    ///executions, and is stops only after the same amount (or more)
   5.292 +    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
   5.293 +    ///of recursive functions.
   5.294 +    ///
   5.295 +
   5.296 +    ///@{
   5.297 +
   5.298 +    ///Reset and stop the time counters
   5.299 +
   5.300 +    ///This function resets and stops the time counters
   5.301 +    ///\sa restart()
   5.302 +    void reset()
   5.303 +    {
   5.304 +      _running=0;
   5.305 +      _reset();
   5.306 +    }
   5.307 +
   5.308 +    ///Start the time counters
   5.309 +    
   5.310 +    ///This function starts the time counters.
   5.311 +    ///
   5.312 +    ///If the timer is started more than ones, it will remain running
   5.313 +    ///until the same amount of \ref stop() is called.
   5.314 +    ///\sa stop()
   5.315 +    void start() 
   5.316 +    {
   5.317 +      if(_running) _running++;
   5.318 +      else {
   5.319 +	_running=1;
   5.320 +	TimeStamp t;
   5.321 +	t.stamp();
   5.322 +	start_time=t-start_time;
   5.323 +      }
   5.324 +    }
   5.325 +
   5.326 +    
   5.327 +    ///Stop the time counters
   5.328 +
   5.329 +    ///This function stops the time counters. If start() was executed more than
   5.330 +    ///once, then the same number of stop() execution is necessary the really
   5.331 +    ///stop the timer.
   5.332 +    /// 
   5.333 +    ///\sa halt()
   5.334 +    ///\sa start()
   5.335 +    ///\sa restart()
   5.336 +    ///\sa reset()
   5.337 +
   5.338 +    void stop() 
   5.339 +    {
   5.340 +      if(_running && !--_running) {
   5.341 +	TimeStamp t;
   5.342 +	t.stamp();
   5.343 +	start_time=t-start_time;
   5.344 +      }
   5.345 +    }
   5.346 +
   5.347 +    ///Halt (i.e stop immediately) the time counters
   5.348 +
   5.349 +    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
   5.350 +    ///is a faster
   5.351 +    ///equivalent of the following.
   5.352 +    ///\code
   5.353 +    ///  while(t.running()) t.stop()
   5.354 +    ///\endcode
   5.355 +    ///
   5.356 +    ///
   5.357 +    ///\sa stop()
   5.358 +    ///\sa restart()
   5.359 +    ///\sa reset()
   5.360 +
   5.361 +    void halt() 
   5.362 +    {
   5.363 +      if(_running) {
   5.364 +	_running=0;
   5.365 +	TimeStamp t;
   5.366 +	t.stamp();
   5.367 +	start_time=t-start_time;
   5.368 +      }
   5.369 +    }
   5.370 +
   5.371 +    ///Returns the running state of the timer
   5.372 +
   5.373 +    ///This function returns the number of stop() exections that is
   5.374 +    ///necessary to really stop the timer.
   5.375 +    ///For example the timer
   5.376 +    ///is running if and only if the return value is \c true
   5.377 +    ///(i.e. greater than
   5.378 +    ///zero).
   5.379 +    int running()  { return _running; }
   5.380 +    
   5.381 +    
   5.382 +    ///Restart the time counters
   5.383 +
   5.384 +    ///This function is a shorthand for
   5.385 +    ///a reset() and a start() calls.
   5.386 +    ///
   5.387 +    void restart() 
   5.388 +    {
   5.389 +      reset();
   5.390 +      start();
   5.391 +    }
   5.392 +    
   5.393 +    ///@}
   5.394 +
   5.395 +    ///\name Query Functions for the ellapsed time
   5.396 +
   5.397 +    ///@{
   5.398 +
   5.399 +    ///Gives back the ellapsed user time of the process
   5.400 +    double userTime() const
   5.401 +    {
   5.402 +      return operator TimeStamp().userTime();
   5.403 +    }
   5.404 +    ///Gives back the ellapsed system time of the process
   5.405 +    double systemTime() const
   5.406 +    {
   5.407 +      return operator TimeStamp().systemTime();
   5.408 +    }
   5.409 +    ///Gives back the ellapsed user time of the process' children
   5.410 +    double cUserTime() const
   5.411 +    {
   5.412 +      return operator TimeStamp().cUserTime();
   5.413 +    }
   5.414 +    ///Gives back the ellapsed user time of the process' children
   5.415 +    double cSystemTime() const
   5.416 +    {
   5.417 +      return operator TimeStamp().cSystemTime();
   5.418 +    }
   5.419 +    ///Gives back the ellapsed real time
   5.420 +    double realTime() const
   5.421 +    {
   5.422 +      return operator TimeStamp().realTime();
   5.423 +    }
   5.424 +    ///Computes the ellapsed time
   5.425 +
   5.426 +    ///This conversion computes the ellapsed time, therefore you can print
   5.427 +    ///the ellapsed time like this.
   5.428 +    ///\code
   5.429 +    ///  Timer t;
   5.430 +    ///  doSomething();
   5.431 +    ///  std::cout << t << '\n';
   5.432 +    ///\endcode
   5.433 +    operator TimeStamp () const
   5.434 +    {
   5.435 +      TimeStamp t;
   5.436 +      t.stamp();
   5.437 +      return _running?t-start_time:start_time;
   5.438 +    }
   5.439 +
   5.440 +
   5.441 +    ///@}
   5.442 +  };
   5.443 +
   5.444 +  ///Same as \ref Timer but prints a report on destruction.
   5.445 +
   5.446 +  ///Same as \ref Timer but prints a report on destruction.
   5.447 +  ///This example shows its usage.
   5.448 +  ///\code
   5.449 +  ///  void myAlg(ListGraph &g,int n)
   5.450 +  ///  {
   5.451 +  ///    TimeReport tr("Running time of myAlg: ");
   5.452 +  ///    ... //Here comes the algorithm
   5.453 +  ///  }
   5.454 +  ///\endcode
   5.455 +  ///
   5.456 +  ///\sa Timer
   5.457 +  ///\sa NoTimeReport
   5.458 +  ///\todo There is no test case for this
   5.459 +  class TimeReport : public Timer 
   5.460 +  {
   5.461 +    std::string _title;
   5.462 +    std::ostream &_os;
   5.463 +  public:
   5.464 +    ///\e
   5.465 +
   5.466 +    ///\param title This text will be printed before the ellapsed time.
   5.467 +    ///\param os The stream to print the report to.
   5.468 +    ///\param run Sets whether the timer should start immediately.
   5.469 +
   5.470 +    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
   5.471 +      : Timer(run), _title(title), _os(os){}
   5.472 +    ///\e Prints the ellapsed time on destruction.
   5.473 +    ~TimeReport() 
   5.474 +    {
   5.475 +      _os << _title << *this << std::endl;
   5.476 +    }
   5.477 +  };
   5.478 +      
   5.479 +  ///'Do nothing' version of \ref TimeReport
   5.480 +
   5.481 +  ///\sa TimeReport
   5.482 +  ///
   5.483 +  class NoTimeReport
   5.484 +  {
   5.485 +  public:
   5.486 +    ///\e
   5.487 +    NoTimeReport(std::string,std::ostream &,bool) {}
   5.488 +    ///\e
   5.489 +    NoTimeReport(std::string,std::ostream &) {}
   5.490 +    ///\e
   5.491 +    NoTimeReport(std::string) {}
   5.492 +    ///\e Do nothing.
   5.493 +    ~NoTimeReport() {}
   5.494 +
   5.495 +    operator TimeStamp () const { return TimeStamp(); }
   5.496 +    void reset() {}
   5.497 +    void start() {}
   5.498 +    void stop() {}
   5.499 +    void halt() {} 
   5.500 +    int running() { return 0; }
   5.501 +    void restart() {}
   5.502 +    double userTime() const { return 0; }
   5.503 +    double systemTime() const { return 0; }
   5.504 +    double cUserTime() const { return 0; }
   5.505 +    double cSystemTime() const { return 0; }
   5.506 +    double realTime() const { return 0; }
   5.507 +  };
   5.508 +      
   5.509 +  ///Tool to measure the running time more exactly.
   5.510 +  
   5.511 +  ///This function calls \c f several times and returns the average
   5.512 +  ///running time. The number of the executions will be choosen in such a way
   5.513 +  ///that the full real running time will be roughly between \c min_time
   5.514 +  ///and <tt>2*min_time</tt>.
   5.515 +  ///\param f the function object to be measured.
   5.516 +  ///\param min_time the minimum total running time.
   5.517 +  ///\retval num if it is not \c NULL, then the actual
   5.518 +  ///        number of execution of \c f will be written into <tt>*num</tt>.
   5.519 +  ///\retval full_time if it is not \c NULL, then the actual
   5.520 +  ///        total running time will be written into <tt>*full_time</tt>.
   5.521 +  ///\return The average running time of \c f.
   5.522 +  
   5.523 +  template<class F>
   5.524 +  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
   5.525 +                            TimeStamp *full_time=NULL)
   5.526 +  {
   5.527 +    TimeStamp full;
   5.528 +    unsigned int total=0;
   5.529 +    Timer t;
   5.530 +    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
   5.531 +      for(;total<tn;total++) f();
   5.532 +      full=t;
   5.533 +    }
   5.534 +    if(num) *num=total;
   5.535 +    if(full_time) *full_time=full;
   5.536 +    return full/total;
   5.537 +  }
   5.538 +  
   5.539 +  /// @}  
   5.540 +
   5.541 +
   5.542 +} //namespace lemon
   5.543 +
   5.544 +#endif //LEMON_TIME_MEASURE_H
     6.1 --- a/test/Makefile.am	Tue Apr 08 22:51:26 2008 +0200
     6.2 +++ b/test/Makefile.am	Sat Apr 12 20:38:51 2008 +0100
     6.3 @@ -9,6 +9,7 @@
     6.4  
     6.5  check_PROGRAMS += \
     6.6  	test/bfs_test \
     6.7 +        test/counter_test \
     6.8  	test/dfs_test \
     6.9  	test/digraph_test \
    6.10          test/dim_test \
    6.11 @@ -20,12 +21,14 @@
    6.12          test/path_test \
    6.13          test/test_tools_fail \
    6.14          test/test_tools_pass \
    6.15 +        test/time_measure_test \
    6.16  	test/unionfind_test
    6.17  
    6.18  TESTS += $(check_PROGRAMS)
    6.19  XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
    6.20  
    6.21  test_bfs_test_SOURCES = test/bfs_test.cc
    6.22 +test_counter_test_SOURCES = test/counter_test.cc
    6.23  test_dfs_test_SOURCES = test/dfs_test.cc
    6.24  test_digraph_test_SOURCES = test/digraph_test.cc
    6.25  test_dim_test_SOURCES = test/dim_test.cc
    6.26 @@ -38,4 +41,5 @@
    6.27  test_random_test_SOURCES = test/random_test.cc
    6.28  test_test_tools_fail_SOURCES = test/test_tools_fail.cc
    6.29  test_test_tools_pass_SOURCES = test/test_tools_pass.cc
    6.30 +test_time_measure_test_SOURCES = test/time_measure_test.cc
    6.31  test_unionfind_test_SOURCES = test/unionfind_test.cc
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/counter_test.cc	Sat Apr 12 20:38:51 2008 +0100
     7.3 @@ -0,0 +1,66 @@
     7.4 +/* -*- C++ -*-
     7.5 + *
     7.6 + * This file is a part of LEMON, a generic C++ optimization library
     7.7 + *
     7.8 + * Copyright (C) 2003-2008
     7.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    7.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    7.11 + *
    7.12 + * Permission to use, modify and distribute this software is granted
    7.13 + * provided that this copyright notice appears in all copies. For
    7.14 + * precise terms see the accompanying LICENSE file.
    7.15 + *
    7.16 + * This software is provided "AS IS" with no warranty of any kind,
    7.17 + * express or implied, and with no claim as to its suitability for any
    7.18 + * purpose.
    7.19 + *
    7.20 + */
    7.21 +
    7.22 +#include <lemon/counter.h>
    7.23 +
    7.24 +///\file \brief Test cases for time_measure.h
    7.25 +///
    7.26 +///\todo To be extended
    7.27 +
    7.28 +
    7.29 +int fibonacci(int f) 
    7.30 +{
    7.31 +  static lemon::Counter count("Fibonacci steps: ");
    7.32 +  count++;
    7.33 +  if(f<1) return 0;
    7.34 +  else if(f==1) return 1;
    7.35 +  else return fibonacci(f-1)+fibonacci(f-2);
    7.36 +}
    7.37 +
    7.38 +int main()
    7.39 +{
    7.40 +  fibonacci(10);
    7.41 +  
    7.42 +  {  
    7.43 +    typedef lemon::Counter MyCounter;
    7.44 +    MyCounter c("Main counter: ");
    7.45 +    c++;
    7.46 +    c++;
    7.47 +    MyCounter::SubCounter d(c,"Subcounter: ");
    7.48 +    d++;
    7.49 +    d++;
    7.50 +    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
    7.51 +    e++;
    7.52 +    e++;
    7.53 +  }
    7.54 +  
    7.55 +  {
    7.56 +    typedef lemon::NoCounter MyCounter;
    7.57 +    MyCounter c("Main counter: ");
    7.58 +    c++;
    7.59 +    c++;
    7.60 +    MyCounter::SubCounter d(c,"Subcounter: ");
    7.61 +    d++;
    7.62 +    d++;
    7.63 +    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
    7.64 +    e++;
    7.65 +    e++;
    7.66 +  }
    7.67 +
    7.68 +  return 0;
    7.69 +}
     8.1 --- a/test/error_test.cc	Tue Apr 08 22:51:26 2008 +0200
     8.2 +++ b/test/error_test.cc	Sat Apr 12 20:38:51 2008 +0100
     8.3 @@ -39,165 +39,21 @@
     8.4    LEMON_ASSERT(true, "This is a fault message");
     8.5  }
     8.6  
     8.7 -void no_assertion_exception_disable() {
     8.8 -  LEMON_ASSERT(true, Exception());
     8.9 -}
    8.10 -
    8.11  void assertion_text_disable() {
    8.12    LEMON_ASSERT(false, "This is a fault message");
    8.13  }
    8.14  
    8.15 -void assertion_exception_disable() {
    8.16 -  LEMON_ASSERT(false, Exception());
    8.17 -}
    8.18 -
    8.19  void fixme_disable() {
    8.20    LEMON_FIXME("fixme_disable() is fixme!");
    8.21  }
    8.22  
    8.23  void check_assertion_disable() {
    8.24    no_assertion_text_disable();
    8.25 -  no_assertion_exception_disable();
    8.26 -  assertion_exception_disable();
    8.27    assertion_text_disable();
    8.28    fixme_disable();
    8.29  }
    8.30  #undef LEMON_DISABLE_ASSERTS
    8.31  
    8.32 -
    8.33 -#define LEMON_ASSERT_ERROR
    8.34 -#include <lemon/assert.h>
    8.35 -
    8.36 -void no_assertion_text_error() {
    8.37 -  LEMON_ASSERT(true, "This is a fault message");
    8.38 -}
    8.39 -
    8.40 -void no_assertion_exception_error() {
    8.41 -  LEMON_ASSERT(true, Exception());
    8.42 -}
    8.43 -
    8.44 -void assertion_text_error() {
    8.45 -  LEMON_ASSERT(false, "This is a fault message");
    8.46 -}
    8.47 -
    8.48 -void assertion_exception_error() {
    8.49 -  LEMON_ASSERT(false, Exception());
    8.50 -}
    8.51 -
    8.52 -void fixme_error() {
    8.53 -  LEMON_FIXME("fixme_error() is fixme!");
    8.54 -}
    8.55 -
    8.56 -void check_assertion_error() {
    8.57 -  no_assertion_text_error();
    8.58 -  no_assertion_exception_error();
    8.59 -  try {
    8.60 -    assertion_exception_error();
    8.61 -    check(false, "Assertion error");
    8.62 -  } catch (const AssertionFailedError& e) {
    8.63 -  }
    8.64 -
    8.65 -  try {
    8.66 -    assertion_text_error();
    8.67 -    check(false, "Assertion error");
    8.68 -  } catch (const AssertionFailedError& e) {
    8.69 -  }
    8.70 -
    8.71 -  try {
    8.72 -    fixme_error();
    8.73 -    check(false, "Assertion error");
    8.74 -  } catch (const AssertionFailedError& e) {
    8.75 -  }
    8.76 -}
    8.77 -#undef LEMON_ASSERT_ERROR
    8.78 -
    8.79 -#define LEMON_ASSERT_EXCEPTION
    8.80 -#include <lemon/assert.h>
    8.81 -
    8.82 -void no_assertion_text_exception() {
    8.83 -  LEMON_ASSERT(true, "This is a fault message");
    8.84 -}
    8.85 -
    8.86 -void no_assertion_exception_exception() {
    8.87 -  LEMON_ASSERT(true, Exception());
    8.88 -}
    8.89 -
    8.90 -void assertion_text_exception() {
    8.91 -  LEMON_ASSERT(false, "This is a fault message");
    8.92 -}
    8.93 -
    8.94 -void assertion_exception_exception() {
    8.95 -  LEMON_ASSERT(false, Exception());
    8.96 -}
    8.97 -
    8.98 -void fixme_exception() {
    8.99 -  LEMON_FIXME("fixme_exception() is fixme!");
   8.100 -}
   8.101 -
   8.102 -void check_assertion_exception() {
   8.103 -  no_assertion_text_exception();
   8.104 -  no_assertion_exception_exception();
   8.105 -  try {
   8.106 -    assertion_exception_exception();
   8.107 -    check(false, "Assertion error");
   8.108 -  } catch (const Exception& e) {
   8.109 -  }
   8.110 -
   8.111 -  try {
   8.112 -    assertion_text_exception();
   8.113 -    check(false, "Assertion error");
   8.114 -  } catch (const AssertionFailedError& e) {
   8.115 -  }
   8.116 -
   8.117 -  try {
   8.118 -    assertion_text_exception();
   8.119 -    check(false, "Assertion error");
   8.120 -  } catch (const AssertionFailedError& e) {
   8.121 -  }
   8.122 -
   8.123 -  try {
   8.124 -    fixme_exception();
   8.125 -    check(false, "Assertion error");
   8.126 -  } catch (const AssertionFailedError& e) {
   8.127 -  }
   8.128 -}
   8.129 -#undef LEMON_ASSERT_EXCEPTION
   8.130 -
   8.131 -#define LEMON_ASSERT_LOG
   8.132 -
   8.133 -#include <lemon/assert.h>
   8.134 -
   8.135 -void no_assertion_text_log() {
   8.136 -  LEMON_ASSERT(true, "This is a fault message");
   8.137 -}
   8.138 -
   8.139 -void no_assertion_exception_log() {
   8.140 -  LEMON_ASSERT(true, Exception());
   8.141 -}
   8.142 -
   8.143 -void assertion_text_log() {
   8.144 -  LEMON_ASSERT(false, "This is a fault message");
   8.145 -}
   8.146 -
   8.147 -void assertion_exception_log() {
   8.148 -  LEMON_ASSERT(false, Exception());
   8.149 -}
   8.150 -
   8.151 -void fixme_log() {
   8.152 -  LEMON_FIXME("fixme_log() is fixme!");
   8.153 -}
   8.154 -
   8.155 -void check_assertion_log() {
   8.156 -  no_assertion_text_log();
   8.157 -  no_assertion_exception_log();
   8.158 -  std::cerr << "The next 3 failure messages are expected: " << std::endl;
   8.159 -  assertion_exception_log();
   8.160 -  assertion_text_log();
   8.161 -  fixme_log();
   8.162 -  std::cerr << "End of expected error messages" << std::endl;
   8.163 -}
   8.164 -#undef LEMON_ASSERT_LOG
   8.165 -
   8.166  #define LEMON_ASSERT_CUSTOM
   8.167  
   8.168  static int cnt = 0;
   8.169 @@ -206,17 +62,6 @@
   8.170    ++cnt;
   8.171  }
   8.172  
   8.173 -void my_assert_handler(const char*, int, const char*, 
   8.174 -		       const std::exception&, const char*) {
   8.175 -  ++cnt;
   8.176 -}
   8.177 -
   8.178 -void my_assert_handler(const char*, int, const char*, 
   8.179 -		       const std::string&, const char*) {
   8.180 -  ++cnt;
   8.181 -}
   8.182 -
   8.183 -
   8.184  #define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
   8.185  #include <lemon/assert.h>
   8.186  
   8.187 @@ -224,29 +69,19 @@
   8.188    LEMON_ASSERT(true, "This is a fault message");
   8.189  }
   8.190  
   8.191 -void no_assertion_exception_custom() {
   8.192 -  LEMON_ASSERT(true, Exception());
   8.193 -}
   8.194 -
   8.195  void assertion_text_custom() {
   8.196    LEMON_ASSERT(false, "This is a fault message");
   8.197  }
   8.198  
   8.199 -void assertion_exception_custom() {
   8.200 -  LEMON_ASSERT(false, Exception());
   8.201 -}
   8.202 -
   8.203  void fixme_custom() {
   8.204    LEMON_FIXME("fixme_custom() is fixme!");
   8.205  }
   8.206  
   8.207  void check_assertion_custom() {
   8.208    no_assertion_text_custom();
   8.209 -  no_assertion_exception_custom();
   8.210 -  assertion_exception_custom();
   8.211    assertion_text_custom();
   8.212    fixme_custom();
   8.213 -  check(cnt == 3, "The custom assert handler does not work");
   8.214 +  check(cnt == 2, "The custom assert handler does not work");
   8.215  }
   8.216  
   8.217  #undef LEMON_ASSERT_CUSTOM
   8.218 @@ -254,9 +89,6 @@
   8.219  
   8.220  int main() {
   8.221    check_assertion_disable();
   8.222 -  check_assertion_error();
   8.223 -  check_assertion_exception();
   8.224 -  check_assertion_log();
   8.225    check_assertion_custom();
   8.226  
   8.227    return 0;
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/time_measure_test.cc	Sat Apr 12 20:38:51 2008 +0100
     9.3 @@ -0,0 +1,63 @@
     9.4 +/* -*- C++ -*-
     9.5 + *
     9.6 + * This file is a part of LEMON, a generic C++ optimization library
     9.7 + *
     9.8 + * Copyright (C) 2003-2008
     9.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    9.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    9.11 + *
    9.12 + * Permission to use, modify and distribute this software is granted
    9.13 + * provided that this copyright notice appears in all copies. For
    9.14 + * precise terms see the accompanying LICENSE file.
    9.15 + *
    9.16 + * This software is provided "AS IS" with no warranty of any kind,
    9.17 + * express or implied, and with no claim as to its suitability for any
    9.18 + * purpose.
    9.19 + *
    9.20 + */
    9.21 +
    9.22 +#include <lemon/time_measure.h>
    9.23 +
    9.24 +///\file \brief Test cases for time_measure.h
    9.25 +///
    9.26 +///\todo To be extended
    9.27 +
    9.28 +
    9.29 +using namespace lemon;
    9.30 +
    9.31 +void f() 
    9.32 +{
    9.33 +  double d=0;
    9.34 +  for(int i=0;i<1000;i++)
    9.35 +    d+=0.1;
    9.36 +}
    9.37 +
    9.38 +void g() 
    9.39 +{
    9.40 +  static Timer T;
    9.41 +  
    9.42 +  for(int i=0;i<1000;i++)
    9.43 +    TimeStamp x(T);
    9.44 +}
    9.45 +
    9.46 +int main()
    9.47 +{
    9.48 +  Timer T;
    9.49 +  unsigned int n;
    9.50 +  for(n=0;T.realTime()<1.0;n++) ;
    9.51 +  std::cout << T << " (" << n << " time queries)\n";
    9.52 +  T.restart();
    9.53 +  while(T.realTime()<2.0) ;
    9.54 +  std::cout << T << '\n';
    9.55 +  TimeStamp full;
    9.56 +  TimeStamp t;
    9.57 +  t=runningTimeTest(f,1,&n,&full);
    9.58 +  std::cout << t << " (" << n << " tests)\n";
    9.59 +  std::cout << "Total: " << full << "\n";
    9.60 +  
    9.61 +  t=runningTimeTest(g,1,&n,&full);
    9.62 +  std::cout << t << " (" << n << " tests)\n";
    9.63 +  std::cout << "Total: " << full << "\n";
    9.64 +  
    9.65 +  return 0;
    9.66 +}