# HG changeset patch
# User Alpar Juttner <alpar@cs.elte.hu>
# Date 1208029131 -3600
# Node ID ae7785fe84315de6be35a182420b6369e851f00d
# Parent  8899d1891a3c63a87d251d8dde847c308e741c34# Parent  35840c5aa696a13b32a242f1cdc419efb3b18913
Merge

diff -r 8899d1891a3c -r ae7785fe8431 lemon/Makefile.am
--- a/lemon/Makefile.am	Tue Apr 08 22:51:26 2008 +0200
+++ b/lemon/Makefile.am	Sat Apr 12 20:38:51 2008 +0100
@@ -20,6 +20,7 @@
 	lemon/assert.h \
         lemon/bfs.h \
         lemon/bin_heap.h \
+        lemon/counter.h \
         lemon/dfs.h \
         lemon/dijkstra.h \
         lemon/dim2.h \
@@ -32,6 +33,7 @@
 	lemon/path.h \
         lemon/random.h \
 	lemon/smart_graph.h \
+        lemon/time_measure.h \
         lemon/tolerance.h \
 	lemon/unionfind.h
 
diff -r 8899d1891a3c -r ae7785fe8431 lemon/assert.h
--- a/lemon/assert.h	Tue Apr 08 22:51:26 2008 +0200
+++ b/lemon/assert.h	Sat Apr 12 20:38:51 2008 +0100
@@ -27,71 +27,6 @@
 
 namespace lemon {
 
-  /// @{
-
-  ///\e
-  class AssertionFailedError : public LogicError {
-  protected:
-    const char *_assertion;
-    const char *_file;
-    int _line;
-    const char *_function;
-    const char *_message;
-
-    mutable ExceptionMember<std::string> _message_holder;
-  public:
-    ///\e
-    AssertionFailedError(const char *file, int line, const char *function,
-			 const char *msg, const char *assertion = 0) :
-      _assertion(assertion), _file(file), _line(line), 
-      _function(function), _message(msg) {}
-
-    ///\e
-    const char* assertion() const { return _assertion; }
-    ///\e
-    const char* message() const { return _message; }
-    ///\e
-    const char* file() const { return _file; }
-    ///\e
-    const char* function() const { return _function; }
-    ///\e
-    int line() const { return _line; }
-
-
-    virtual const char* what() const throw() {
-      try {
-	std::ostringstream ostr;
-	ostr << _file << ":" << _line << ": ";
-	if (_function)
-	  ostr << _function << ": ";
-	ostr << _message;
-	if (_assertion)
-	   ostr << " (assertion '" << _assertion << "' failed)";
-	_message_holder.set(ostr.str());
-	return ostr.str().c_str();
-      }
-      catch(...) {}
-      if( _message_holder.valid() ) return _message_holder.get().c_str();
-      return "lemon::AssertionFailedError";
-    }
-    virtual ~AssertionFailedError() throw() {}
-  };
-
-
-  inline void assert_fail_log(const char *file, int line,
-			      const char *function,
-			      const std::exception& exception, 
-			      const char *assertion)
-  {
-    std::cerr << file << ":" << line << ": ";
-    if (function)
-      std::cerr << function << ": ";
-    std::cerr << exception.what();
-    if (assertion)
-      std::cerr << " (assertion '" << assertion << "' failed)";
-    std::cerr << std::endl;
-  }
-
   inline void assert_fail_log(const char *file, int line, const char *function,
 			      const char *message, const char *assertion)
   {
@@ -104,21 +39,6 @@
     std::cerr << std::endl;
   }
 
-  inline void assert_fail_log(const char *file, int line, const char *function, 
-			      const std::string& message, const char *assertion)
-  {
-    assert_fail_log(file, line, function, message.c_str(), assertion);
-  }
-
-  inline void assert_fail_abort(const char *file, int line, 
-				const char *function,
-				const std::exception& exception,
-				const char *assertion)
-  {
-    assert_fail_log(file, line, function, exception, assertion);
-    std::abort();
-  }
-
   inline void assert_fail_abort(const char *file, int line,
 				const char *function, const char* message,
 				const char *assertion)
@@ -127,86 +47,37 @@
     std::abort();
   }
 
-  inline void assert_fail_abort(const char *file, int line, 
-				const char *function, 
-				const std::string& message,
-				const char *assertion)
-  {
-    assert_fail_log(file, line, function, message.c_str(), assertion);
-    std::abort();
+  namespace _assert_bits {
+    
+    
+    inline const char* cstringify(const std::string& str) {
+      return str.c_str();
+    }
+
+    inline const char* cstringify(const char* str) {
+      return str;
+    }    
   }
+}
 
-  inline void assert_fail_error(const char *file, int line, 
-				  const char *function,
-				  const std::exception& exception,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, 
-			       exception.what(), assertion);
-  }
-
-  inline void assert_fail_error(const char *file, int line,
-				  const char *function, const char *message,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message, assertion);
-  }
-
-  inline void assert_fail_error(const char *file, int line,
-				  const char *function, 
-				  const std::string& message,
-				  const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
-  }
-
-  template <typename Exception>
-  inline void assert_fail_exception(const char *, int, const char *,
-				    const Exception& exception,
-				    const char *, const std::exception* = 
-				    static_cast<const Exception*>(0))
-  {
-    throw exception;
-  }
-
-  inline void assert_fail_exception(const char *file, int line,
-				    const char *function, const char *message,
-				    const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message, assertion);
-  }
-
-  inline void assert_fail_exception(const char *file, int line, 
-				    const char *function, 
-				    const std::string& message,
-				    const char *assertion)
-  {
-    throw AssertionFailedError(file, line, function, message.c_str(), assertion);
-  }
-
-/// @}
-
-}
 #endif // LEMON_ASSERT_H
 
 #undef LEMON_ASSERT
 #undef LEMON_FIXME
+#undef LEMON_DEBUG
 
 #if (defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
   (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
-  (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
-  (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +		\
   (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
 #error "LEMON assertion system is not set properly"
 #endif
 
 #if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) +		\
      (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +		\
-     (defined(LEMON_ASSERT_ERROR) ? 1 : 0) +		\
-     (defined(LEMON_ASSERT_EXCEPTION) ? 1 : 0) +	\
      (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||	\
      defined(LEMON_ENABLE_ASSERTS)) &&			\
-  defined(LEMON_DISABLE_ASSERTS)
+  (defined(LEMON_DISABLE_ASSERTS) ||			\
+   defined(NDEBUG))
 #error "LEMON assertion system is not set properly"
 #endif
 
@@ -217,26 +88,20 @@
 #elif defined LEMON_ASSERT_ABORT
 #  undef LEMON_ASSERT_HANDLER
 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
-#elif defined LEMON_ASSERT_ERROR
-#  undef LEMON_ASSERT_HANDLER
-#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_error
-#elif defined LEMON_ASSERT_EXCEPTION
-#  undef LEMON_ASSERT_HANDLER
-#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_exception
 #elif defined LEMON_ASSERT_CUSTOM
 #  undef LEMON_ASSERT_HANDLER
 #  ifndef LEMON_CUSTOM_ASSERT_HANDLER
 #    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
 #  endif
 #  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
-#elif defined LEMON_ENABLE_ASSERTS
+#elif defined LEMON_DISABLE_ASSERTS
 #  undef LEMON_ASSERT_HANDLER
+#elif defined NDEBUG
+#  undef LEMON_ASSERT_HANDLER
+#else
 #  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
-#else
-#  undef LEMON_ASSERT_HANDLER
 #endif
 
-
 #ifndef LEMON_FUNCTION_NAME
 #  define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
 #endif
@@ -247,24 +112,24 @@
 ///
 /// \brief Macro for assertion with customizable message
 ///
-/// Macro for assertion with customizable message.  
-/// \param exp An expression that must be convertible to \c bool.
-/// If it is \c false, then an assertion is raised. The concrete
-/// behaviour depends on the settings of the assertion system.
-/// \param msg A <tt>const char*</tt>, a <tt>const std::string&</tt> or
-/// a <tt>const std::exception&</tt> parameter, which can be used to
-/// provide information about the circumstances of the failed assertion.
+/// Macro for assertion with customizable message.  \param exp An
+/// expression that must be convertible to \c bool.  If it is \c
+/// false, then an assertion is raised. The concrete behaviour depends
+/// on the settings of the assertion system.  \param msg A <tt>const
+/// char*</tt> parameter, which can be used to provide information
+/// about the circumstances of the failed assertion.
 ///
-/// The assertions are disabled in the default behaviour.
-/// You can enable them with the following code:
+/// The assertions are enabled in the default behaviour.
+/// You can disable them with the following code:
 /// \code
-/// #define LEMON_ENABLE_ASSERTS
+/// #define LEMON_DISABLE_ASSERTS
 /// \endcode
 /// or with compilation parameters:
 /// \code
-/// g++ -DLEMON_ENABLE_ASSERTS
-/// make CXXFLAGS='-DLEMON_ENABLE_ASSERTS'
+/// g++ -DLEMON_DISABLE_ASSERTS
+/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
 /// \endcode
+/// The checking is also disabled when the standard macro \c NDEBUG is defined.
 /// 
 /// The LEMON assertion system has a wide range of customization
 /// properties. As a default behaviour the failed assertion prints a
@@ -274,38 +139,22 @@
 ///
 /// - \c LEMON_ASSERT_LOG The failed assertion prints a short log
 ///   message to the standard error and continues the execution.
-/// - \c LEMON_ASSERT_ABORT This mode is similar to the
-///   \c LEMON_ASSERT_LOG, but it aborts the program. It is the default
-///   behaviour mode when the assertions are enabled with
-///   \c LEMON_ENABLE_ASSERTS.
-/// - \c LEMON_ASSERT_ERROR The assertion throws an
-///   \ref lemon::AssertionFailedError "AssertionFailedError".
-///   If the \c msg parameter is an exception, then the result of the
-///   \ref lemon::Exception::what() "what()" member function is passed
-///   as error message.
-/// - \c LEMON_ASSERT_EXCEPTION If the specified \c msg is an
-///   exception, then it raised directly (solving that the exception
-///   can not be thrown polymorphically), otherwise an \ref
-///   lemon::AssertionFailedError "AssertionFailedError" is thrown with
-///   the given parameters.
+/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c
+///   LEMON_ASSERT_LOG, but it aborts the program. It is the default
+///   behaviour.
 /// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
-///   functions. Three overloaded functions should be defined with the
-///   following parameter lists:
+///   function.
 ///   \code
 ///     void custom_assert_handler(const char* file, int line, const char* function,
 ///                                const char* message, const char* assertion);
-///     void custom_assert_handler(const char* file, int line, const char* function,
-///                                const std::string& message, const char* assertion);
-///     void custom_assert_handler(const char* file, int line, const char* function,
-///                                const std::exception& message, const char* assertion);
 ///   \endcode
-///   The name of the functions should be defined as the \c
+///   The name of the function should be defined as the \c
 ///   LEMON_CUSTOM_ASSERT_HANDLER macro name. 
 ///   \code
 ///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
 ///   \endcode
-///   Whenever an assertion is occured, one of the custom assertion
-///   handlers is called with appropiate parameters.
+///   Whenever an assertion is occured, the custom assertion
+///   handler is called with appropiate parameters.
 ///
 /// The assertion mode can also be changed within one compilation unit.
 /// If the macros are redefined with other settings and the
@@ -315,8 +164,7 @@
   (static_cast<void> (!!(exp) ? 0 : (					\
     LEMON_ASSERT_HANDLER(__FILE__, __LINE__,				\
 			 LEMON_FUNCTION_NAME,				\
-			 msg, #exp), 0)))
-
+			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
 /// \ingroup exceptions
 ///
@@ -327,26 +175,80 @@
 /// \code
 ///   LEMON_ASSERT(false, msg);
 /// \endcode
+///
+/// \see LEMON_ASSERT 
 #  define LEMON_FIXME(msg)						\
-       (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
-			     "FIXME: " msg, static_cast<const char*>(0)))
+  (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
+			::lemon::_assert_bits::cstringify(msg),		\
+			static_cast<const char*>(0)))
+
+/// \ingroup exceptions
+///
+/// \brief Macro for internal assertions
+///
+/// Macro for internal assertions, it is used in the library to check
+/// the consistency of results of algorithms, several pre- and
+/// postconditions and invariants. The checking is disabled by
+/// default, but it can be turned on with the macro \c
+/// LEMON_ENABLE_DEBUG.
+/// \code
+/// #define LEMON_ENABLE_DEBUG
+/// \endcode
+/// or with compilation parameters:
+/// \code
+/// g++ -DLEMON_ENABLE_DEBUG
+/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
+/// \endcode
+///
+/// This macro works like the \c LEMON_ASSERT macro, therefore the
+/// current behaviour depends on the settings of \c LEMON_ASSERT
+/// macro.
+///
+/// \see LEMON_ASSERT 
+#  define LEMON_DEBUG(exp, msg)						\
+  (static_cast<void> (!!(exp) ? 0 : (					\
+    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
+			 LEMON_FUNCTION_NAME,				\
+			 ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
 
 #else
 
 #  ifndef LEMON_ASSERT_HANDLER
 #    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
 #    define LEMON_FIXME(msg) (static_cast<void>(0))
+#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
 #  else
-#    define LEMON_ASSERT(exp, msg)                 \
-       (static_cast<void> (!!(exp) ? 0 : (         \
-         LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
-                              LEMON_FUNCTION_NAME, \
-                              msg, #exp), 0)))
-#    define LEMON_FIXME(msg) \
+#    define LEMON_ASSERT(exp, msg)					\
+       (static_cast<void> (!!(exp) ? 0 : (				\
+        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
+			     LEMON_FUNCTION_NAME,			\
+			     ::lemon::_assert_bits::cstringify(msg),	\
+			     #exp), 0)))
+#    define LEMON_FIXME(msg)						\
        (LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME,	\
-			     "FIXME: " msg,  static_cast<const char*>(0)))
+			     ::lemon::_assert_bits::cstringify(msg),	\
+			     static_cast<const char*>(0)))
+
+#    if LEMON_ENABLE_DEBUG
+#      define LEMON_DEBUG(exp, msg)
+         (static_cast<void> (!!(exp) ? 0 : (         \
+           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,  \
+                                LEMON_FUNCTION_NAME, \
+				::lemon::_assert_bits::cstringify(msg),	\
+				#exp), 0)))
+#    else
+#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
+#    endif
 #  endif
 
 #endif
 
+#ifdef DOXYGEN
 
+
+#else
+
+
+#endif
+
+
diff -r 8899d1891a3c -r ae7785fe8431 lemon/bits/utility.h
--- a/lemon/bits/utility.h	Tue Apr 08 22:51:26 2008 +0200
+++ b/lemon/bits/utility.h	Sat Apr 12 20:38:51 2008 +0100
@@ -21,13 +21,13 @@
 
 // Boost enable_if library
 
-// Copyright 2003 © The Trustees of Indiana University.
+// Copyright 2003 (c) The Trustees of Indiana University.
 
 // Use, modification, and distribution is subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-//    Authors: Jaakko Järvi (jajarvi at osl.iu.edu)
+//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
 //             Jeremiah Willcock (jewillco at osl.iu.edu)
 //             Andrew Lumsdaine (lums at osl.iu.edu)
 
diff -r 8899d1891a3c -r ae7785fe8431 lemon/counter.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/counter.h	Sat Apr 12 20:38:51 2008 +0100
@@ -0,0 +1,181 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_COUNTER_H
+#define LEMON_COUNTER_H
+
+#include <string>
+#include <iostream>
+
+///\ingroup timecount
+///\file
+///\brief Tools for counting steps and events
+
+namespace lemon 
+{
+
+  template<class P> class _NoSubCounter;
+
+  template<class P>
+  class _SubCounter 
+  {
+    P &_parent;
+    std::string _title;
+    std::ostream &_os;
+    int count;
+  public:
+
+    typedef _SubCounter<_SubCounter<P> > SubCounter;
+    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
+
+    _SubCounter(P &parent)
+      : _parent(parent), _title(), _os(std::cerr), count(0) {}
+    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
+      : _parent(parent), _title(title), _os(os), count(0) {}
+    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
+      : _parent(parent), _title(title), _os(os), count(0) {}
+    ~_SubCounter() { 
+      _os << _title << count <<std::endl;
+      _parent+=count;
+    }
+    _SubCounter &operator++() { count++; return *this;}
+    int operator++(int) { return count++; }
+    _SubCounter &operator--() { count--; return *this;}
+    int operator--(int) { return count--; }
+    _SubCounter &operator+=(int c) { count+=c; return *this;}
+    _SubCounter &operator-=(int c) { count-=c; return *this;}
+    void reset(int c=0) {count=c;}
+    operator int() {return count;}
+  };
+
+  template<class P>
+  class _NoSubCounter 
+  {
+    P &_parent;
+  public:
+    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
+    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
+  
+    _NoSubCounter(P &parent) :_parent(parent) {}
+    _NoSubCounter(P &parent,std::string,std::ostream &) 
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,std::string) 
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,const char *,std::ostream &)
+      :_parent(parent) {}
+    _NoSubCounter(P &parent,const char *)
+      :_parent(parent) {}
+    ~_NoSubCounter() {}
+    _NoSubCounter &operator++() { ++_parent; return *this;}
+    int operator++(int) { _parent++; return 0;}
+    _NoSubCounter &operator--() { --_parent; return *this;}
+    int operator--(int) { _parent--; return 0;}
+    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
+    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
+    void reset(int) {}
+    void reset() {}
+    operator int() {return 0;}
+  };
+
+
+  /// \addtogroup timecount
+  /// @{
+
+  ///A counter class
+
+  ///This class makes it easier to count certain events. You can increment
+  ///or decrement the counter using operator++ and operator--.
+  ///A report is automatically printed on destruction.
+  ///\todo More doc
+  class Counter 
+  {
+    std::string _title;
+    std::ostream &_os;
+    int count;
+  public:
+    ///\e
+
+    ///\todo document please.
+    ///
+    typedef _SubCounter<Counter> SubCounter;
+    ///\e
+
+    ///\todo document please.
+    ///
+    typedef _NoSubCounter<Counter> NoSubCounter;
+
+    ///\e
+    Counter() : _title(), _os(std::cerr), count(0) {}
+    ///\e
+    Counter(std::string title,std::ostream &os=std::cerr) 
+      : _title(title), _os(os), count(0) {}
+    ///\e
+    Counter(const char *title,std::ostream &os=std::cerr)
+      : _title(title), _os(os), count(0) {}
+    ///Destructor. Prints the given title and the value of the counter.
+    ~Counter() {
+      _os << _title << count <<std::endl;
+    }
+    ///\e
+    Counter &operator++() { count++; return *this;}
+    ///\e
+    int operator++(int) { return count++;}
+    ///\e
+    Counter &operator--() { count--; return *this;}
+    ///\e
+    int operator--(int) { return count--;}
+    ///\e
+    Counter &operator+=(int c) { count+=c; return *this;}
+    ///\e
+    Counter &operator-=(int c) { count-=c; return *this;}
+    ///\e
+    void reset(int c=0) {count=c;}
+    ///\e
+    operator int() {return count;}
+  };
+
+  ///'Do nothing' version of \ref Counter
+
+  ///'Do nothing' version of \ref Counter.
+  ///\sa Counter
+  class NoCounter
+  {
+  public:
+    typedef _NoSubCounter<NoCounter> SubCounter;
+    typedef _NoSubCounter<NoCounter> NoSubCounter;
+
+    NoCounter() {}
+    NoCounter(std::string,std::ostream &) {}
+    NoCounter(const char *,std::ostream &) {}
+    NoCounter(std::string) {}
+    NoCounter(const char *) {}
+    NoCounter &operator++() { return *this; }
+    int operator++(int) { return 0; }
+    NoCounter &operator--() { return *this; }
+    int operator--(int) { return 0; }
+    NoCounter &operator+=(int) { return *this;}
+    NoCounter &operator-=(int) { return *this;}
+    void reset(int) {}
+    void reset() {}
+    operator int() {return 0;}
+  };
+
+  ///@}
+}
+
+#endif
diff -r 8899d1891a3c -r ae7785fe8431 lemon/time_measure.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/time_measure.h	Sat Apr 12 20:38:51 2008 +0100
@@ -0,0 +1,541 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_TIME_MEASURE_H
+#define LEMON_TIME_MEASURE_H
+
+///\ingroup timecount
+///\file
+///\brief Tools for measuring cpu usage
+
+#include <sys/times.h>
+
+#include <sys/time.h>
+#include <fstream>
+#include <iostream>
+#include <unistd.h>
+
+namespace lemon {
+
+  /// \addtogroup timecount
+  /// @{
+
+  /// A class to store (cpu)time instances.
+
+  /// This class stores five time values.
+  /// - a real time
+  /// - a user cpu time
+  /// - a system cpu time
+  /// - a user cpu time of children
+  /// - a system cpu time of children
+  ///
+  /// TimeStamp's can be added to or substracted from each other and
+  /// they can be pushed to a stream.
+  ///
+  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
+  /// class is what you want to use instead.
+  ///
+  ///\author Alpar Juttner
+
+  class TimeStamp
+  {
+    struct rtms 
+    {
+      double tms_utime;
+      double tms_stime;
+      double tms_cutime;
+      double tms_cstime;
+      rtms() {}
+      rtms(tms ts) : tms_utime(ts.tms_utime), tms_stime(ts.tms_stime),
+		     tms_cutime(ts.tms_cutime), tms_cstime(ts.tms_cstime) {}
+    };
+    rtms ts;
+    double real_time;
+  
+    rtms &getTms() {return ts;}
+    const rtms &getTms() const {return ts;}
+
+    void _reset() { 
+      ts.tms_utime = ts.tms_stime = ts.tms_cutime = ts.tms_cstime = 0; 
+      real_time = 0;
+    }
+
+  public:
+
+    ///Read the current time values of the process
+    void stamp()
+    {
+      timeval tv;
+      tms _ts;
+      times(&_ts);
+      gettimeofday(&tv, 0);real_time=tv.tv_sec+double(tv.tv_usec)/1e6;
+      ts=_ts;
+    }
+  
+    /// Constructor initializing with zero
+    TimeStamp()
+    { _reset(); }
+    ///Constructor initializing with the current time values of the process
+    TimeStamp(void *) { stamp();}
+  
+    ///Set every time value to zero
+    TimeStamp &reset() {_reset();return *this;}
+
+    ///\e
+    TimeStamp &operator+=(const TimeStamp &b)
+    {
+      ts.tms_utime+=b.ts.tms_utime;
+      ts.tms_stime+=b.ts.tms_stime;
+      ts.tms_cutime+=b.ts.tms_cutime;
+      ts.tms_cstime+=b.ts.tms_cstime;
+      real_time+=b.real_time;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator+(const TimeStamp &b) const
+    {
+      TimeStamp t(*this);
+      return t+=b;
+    }
+    ///\e
+    TimeStamp &operator-=(const TimeStamp &b)
+    {
+      ts.tms_utime-=b.ts.tms_utime;
+      ts.tms_stime-=b.ts.tms_stime;
+      ts.tms_cutime-=b.ts.tms_cutime;
+      ts.tms_cstime-=b.ts.tms_cstime;
+      real_time-=b.real_time;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator-(const TimeStamp &b) const
+    {
+      TimeStamp t(*this);
+      return t-=b;
+    }
+    ///\e
+    TimeStamp &operator*=(double b)
+    {
+      ts.tms_utime*=b;
+      ts.tms_stime*=b;
+      ts.tms_cutime*=b;
+      ts.tms_cstime*=b;
+      real_time*=b;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator*(double b) const
+    {
+      TimeStamp t(*this);
+      return t*=b;
+    }
+    friend TimeStamp operator*(double b,const TimeStamp &t);
+    ///\e
+    TimeStamp &operator/=(double b)
+    {
+      ts.tms_utime/=b;
+      ts.tms_stime/=b;
+      ts.tms_cutime/=b;
+      ts.tms_cstime/=b;
+      real_time/=b;
+      return *this;
+    }
+    ///\e
+    TimeStamp operator/(double b) const
+    {
+      TimeStamp t(*this);
+      return t/=b;
+    }
+    ///The time ellapsed since the last call of stamp()
+    TimeStamp ellapsed() const
+    {
+      TimeStamp t(NULL);
+      return t-*this;
+    }
+  
+    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
+  
+    ///Gives back the user time of the process
+    double userTime() const
+    {
+      return double(ts.tms_utime)/sysconf(_SC_CLK_TCK);
+    }
+    ///Gives back the system time of the process
+    double systemTime() const
+    {
+      return double(ts.tms_stime)/sysconf(_SC_CLK_TCK);
+    }
+    ///Gives back the user time of the process' children
+    double cUserTime() const
+    {
+      return double(ts.tms_cutime)/sysconf(_SC_CLK_TCK);
+    }
+    ///Gives back the user time of the process' children
+    double cSystemTime() const
+    {
+      return double(ts.tms_cstime)/sysconf(_SC_CLK_TCK);
+    }
+    ///Gives back the real time
+    double realTime() const {return real_time;}
+  };
+
+  TimeStamp operator*(double b,const TimeStamp &t) 
+  {
+    return t*b;
+  }
+  
+  ///Prints the time counters
+
+  ///Prints the time counters in the following form:
+  ///
+  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
+  ///
+  /// where the values are the
+  /// \li \c u: user cpu time,
+  /// \li \c s: system cpu time,
+  /// \li \c cu: user cpu time of children,
+  /// \li \c cs: system cpu time of children,
+  /// \li \c real: real time.
+  /// \relates TimeStamp
+  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
+  {
+    long cls = sysconf(_SC_CLK_TCK);
+    os << "u: " << double(t.getTms().tms_utime)/cls <<
+      "s, s: " << double(t.getTms().tms_stime)/cls <<
+      "s, cu: " << double(t.getTms().tms_cutime)/cls <<
+      "s, cs: " << double(t.getTms().tms_cstime)/cls <<
+      "s, real: " << t.realTime() << "s";
+    return os;
+  }
+
+  ///Class for measuring the cpu time and real time usage of the process
+
+  ///Class for measuring the cpu time and real time usage of the process.
+  ///It is quite easy-to-use, here is a short example.
+  ///\code
+  /// #include<lemon/time_measure.h>
+  /// #include<iostream>
+  ///
+  /// int main()
+  /// {
+  ///
+  ///   ...
+  ///
+  ///   Timer t;
+  ///   doSomething();
+  ///   std::cout << t << '\n';
+  ///   t.restart();
+  ///   doSomethingElse();
+  ///   std::cout << t << '\n';
+  ///
+  ///   ...
+  ///
+  /// }
+  ///\endcode
+  ///
+  ///The \ref Timer can also be \ref stop() "stopped" and
+  ///\ref start() "started" again, so it is possible to compute collected
+  ///running times.
+  ///
+  ///\warning Depending on the operation system and its actual configuration
+  ///the time counters have a certain (10ms on a typical Linux system)
+  ///granularity.
+  ///Therefore this tool is not appropriate to measure very short times.
+  ///Also, if you start and stop the timer very frequently, it could lead to
+  ///distorted results.
+  ///
+  ///\note If you want to measure the running time of the execution of a certain
+  ///function, consider the usage of \ref TimeReport instead.
+  ///
+  ///\todo This shouldn't be Unix (Linux) specific.
+  ///\sa TimeReport
+  ///
+  ///\author Alpar Juttner
+  class Timer
+  {
+    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
+    TimeStamp start_time; //This is the relativ start-time if the timer
+                          //is _running, the collected _running time otherwise.
+    
+    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
+  
+  public: 
+    ///Constructor.
+
+    ///\param run indicates whether or not the timer starts immediately.
+    ///
+    Timer(bool run=true) :_running(run) {_reset();}
+
+    ///\name Control the state of the timer
+    ///Basically a Timer can be either running or stopped,
+    ///but it provides a bit finer control on the execution.
+    ///The \ref Timer also counts the number of \ref start()
+    ///executions, and is stops only after the same amount (or more)
+    ///\ref stop() "stop()"s. This can be useful e.g. to compute the running time
+    ///of recursive functions.
+    ///
+
+    ///@{
+
+    ///Reset and stop the time counters
+
+    ///This function resets and stops the time counters
+    ///\sa restart()
+    void reset()
+    {
+      _running=0;
+      _reset();
+    }
+
+    ///Start the time counters
+    
+    ///This function starts the time counters.
+    ///
+    ///If the timer is started more than ones, it will remain running
+    ///until the same amount of \ref stop() is called.
+    ///\sa stop()
+    void start() 
+    {
+      if(_running) _running++;
+      else {
+	_running=1;
+	TimeStamp t;
+	t.stamp();
+	start_time=t-start_time;
+      }
+    }
+
+    
+    ///Stop the time counters
+
+    ///This function stops the time counters. If start() was executed more than
+    ///once, then the same number of stop() execution is necessary the really
+    ///stop the timer.
+    /// 
+    ///\sa halt()
+    ///\sa start()
+    ///\sa restart()
+    ///\sa reset()
+
+    void stop() 
+    {
+      if(_running && !--_running) {
+	TimeStamp t;
+	t.stamp();
+	start_time=t-start_time;
+      }
+    }
+
+    ///Halt (i.e stop immediately) the time counters
+
+    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
+    ///is a faster
+    ///equivalent of the following.
+    ///\code
+    ///  while(t.running()) t.stop()
+    ///\endcode
+    ///
+    ///
+    ///\sa stop()
+    ///\sa restart()
+    ///\sa reset()
+
+    void halt() 
+    {
+      if(_running) {
+	_running=0;
+	TimeStamp t;
+	t.stamp();
+	start_time=t-start_time;
+      }
+    }
+
+    ///Returns the running state of the timer
+
+    ///This function returns the number of stop() exections that is
+    ///necessary to really stop the timer.
+    ///For example the timer
+    ///is running if and only if the return value is \c true
+    ///(i.e. greater than
+    ///zero).
+    int running()  { return _running; }
+    
+    
+    ///Restart the time counters
+
+    ///This function is a shorthand for
+    ///a reset() and a start() calls.
+    ///
+    void restart() 
+    {
+      reset();
+      start();
+    }
+    
+    ///@}
+
+    ///\name Query Functions for the ellapsed time
+
+    ///@{
+
+    ///Gives back the ellapsed user time of the process
+    double userTime() const
+    {
+      return operator TimeStamp().userTime();
+    }
+    ///Gives back the ellapsed system time of the process
+    double systemTime() const
+    {
+      return operator TimeStamp().systemTime();
+    }
+    ///Gives back the ellapsed user time of the process' children
+    double cUserTime() const
+    {
+      return operator TimeStamp().cUserTime();
+    }
+    ///Gives back the ellapsed user time of the process' children
+    double cSystemTime() const
+    {
+      return operator TimeStamp().cSystemTime();
+    }
+    ///Gives back the ellapsed real time
+    double realTime() const
+    {
+      return operator TimeStamp().realTime();
+    }
+    ///Computes the ellapsed time
+
+    ///This conversion computes the ellapsed time, therefore you can print
+    ///the ellapsed time like this.
+    ///\code
+    ///  Timer t;
+    ///  doSomething();
+    ///  std::cout << t << '\n';
+    ///\endcode
+    operator TimeStamp () const
+    {
+      TimeStamp t;
+      t.stamp();
+      return _running?t-start_time:start_time;
+    }
+
+
+    ///@}
+  };
+
+  ///Same as \ref Timer but prints a report on destruction.
+
+  ///Same as \ref Timer but prints a report on destruction.
+  ///This example shows its usage.
+  ///\code
+  ///  void myAlg(ListGraph &g,int n)
+  ///  {
+  ///    TimeReport tr("Running time of myAlg: ");
+  ///    ... //Here comes the algorithm
+  ///  }
+  ///\endcode
+  ///
+  ///\sa Timer
+  ///\sa NoTimeReport
+  ///\todo There is no test case for this
+  class TimeReport : public Timer 
+  {
+    std::string _title;
+    std::ostream &_os;
+  public:
+    ///\e
+
+    ///\param title This text will be printed before the ellapsed time.
+    ///\param os The stream to print the report to.
+    ///\param run Sets whether the timer should start immediately.
+
+    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true) 
+      : Timer(run), _title(title), _os(os){}
+    ///\e Prints the ellapsed time on destruction.
+    ~TimeReport() 
+    {
+      _os << _title << *this << std::endl;
+    }
+  };
+      
+  ///'Do nothing' version of \ref TimeReport
+
+  ///\sa TimeReport
+  ///
+  class NoTimeReport
+  {
+  public:
+    ///\e
+    NoTimeReport(std::string,std::ostream &,bool) {}
+    ///\e
+    NoTimeReport(std::string,std::ostream &) {}
+    ///\e
+    NoTimeReport(std::string) {}
+    ///\e Do nothing.
+    ~NoTimeReport() {}
+
+    operator TimeStamp () const { return TimeStamp(); }
+    void reset() {}
+    void start() {}
+    void stop() {}
+    void halt() {} 
+    int running() { return 0; }
+    void restart() {}
+    double userTime() const { return 0; }
+    double systemTime() const { return 0; }
+    double cUserTime() const { return 0; }
+    double cSystemTime() const { return 0; }
+    double realTime() const { return 0; }
+  };
+      
+  ///Tool to measure the running time more exactly.
+  
+  ///This function calls \c f several times and returns the average
+  ///running time. The number of the executions will be choosen in such a way
+  ///that the full real running time will be roughly between \c min_time
+  ///and <tt>2*min_time</tt>.
+  ///\param f the function object to be measured.
+  ///\param min_time the minimum total running time.
+  ///\retval num if it is not \c NULL, then the actual
+  ///        number of execution of \c f will be written into <tt>*num</tt>.
+  ///\retval full_time if it is not \c NULL, then the actual
+  ///        total running time will be written into <tt>*full_time</tt>.
+  ///\return The average running time of \c f.
+  
+  template<class F>
+  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
+                            TimeStamp *full_time=NULL)
+  {
+    TimeStamp full;
+    unsigned int total=0;
+    Timer t;
+    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
+      for(;total<tn;total++) f();
+      full=t;
+    }
+    if(num) *num=total;
+    if(full_time) *full_time=full;
+    return full/total;
+  }
+  
+  /// @}  
+
+
+} //namespace lemon
+
+#endif //LEMON_TIME_MEASURE_H
diff -r 8899d1891a3c -r ae7785fe8431 test/Makefile.am
--- a/test/Makefile.am	Tue Apr 08 22:51:26 2008 +0200
+++ b/test/Makefile.am	Sat Apr 12 20:38:51 2008 +0100
@@ -9,6 +9,7 @@
 
 check_PROGRAMS += \
 	test/bfs_test \
+        test/counter_test \
 	test/dfs_test \
 	test/digraph_test \
         test/dim_test \
@@ -20,12 +21,14 @@
         test/path_test \
         test/test_tools_fail \
         test/test_tools_pass \
+        test/time_measure_test \
 	test/unionfind_test
 
 TESTS += $(check_PROGRAMS)
 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
 
 test_bfs_test_SOURCES = test/bfs_test.cc
+test_counter_test_SOURCES = test/counter_test.cc
 test_dfs_test_SOURCES = test/dfs_test.cc
 test_digraph_test_SOURCES = test/digraph_test.cc
 test_dim_test_SOURCES = test/dim_test.cc
@@ -38,4 +41,5 @@
 test_random_test_SOURCES = test/random_test.cc
 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
 test_test_tools_pass_SOURCES = test/test_tools_pass.cc
+test_time_measure_test_SOURCES = test/time_measure_test.cc
 test_unionfind_test_SOURCES = test/unionfind_test.cc
diff -r 8899d1891a3c -r ae7785fe8431 test/counter_test.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/counter_test.cc	Sat Apr 12 20:38:51 2008 +0100
@@ -0,0 +1,66 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/counter.h>
+
+///\file \brief Test cases for time_measure.h
+///
+///\todo To be extended
+
+
+int fibonacci(int f) 
+{
+  static lemon::Counter count("Fibonacci steps: ");
+  count++;
+  if(f<1) return 0;
+  else if(f==1) return 1;
+  else return fibonacci(f-1)+fibonacci(f-2);
+}
+
+int main()
+{
+  fibonacci(10);
+  
+  {  
+    typedef lemon::Counter MyCounter;
+    MyCounter c("Main counter: ");
+    c++;
+    c++;
+    MyCounter::SubCounter d(c,"Subcounter: ");
+    d++;
+    d++;
+    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
+    e++;
+    e++;
+  }
+  
+  {
+    typedef lemon::NoCounter MyCounter;
+    MyCounter c("Main counter: ");
+    c++;
+    c++;
+    MyCounter::SubCounter d(c,"Subcounter: ");
+    d++;
+    d++;
+    MyCounter::SubCounter::SubCounter e(d,"SubSubCounter: ");
+    e++;
+    e++;
+  }
+
+  return 0;
+}
diff -r 8899d1891a3c -r ae7785fe8431 test/error_test.cc
--- a/test/error_test.cc	Tue Apr 08 22:51:26 2008 +0200
+++ b/test/error_test.cc	Sat Apr 12 20:38:51 2008 +0100
@@ -39,165 +39,21 @@
   LEMON_ASSERT(true, "This is a fault message");
 }
 
-void no_assertion_exception_disable() {
-  LEMON_ASSERT(true, Exception());
-}
-
 void assertion_text_disable() {
   LEMON_ASSERT(false, "This is a fault message");
 }
 
-void assertion_exception_disable() {
-  LEMON_ASSERT(false, Exception());
-}
-
 void fixme_disable() {
   LEMON_FIXME("fixme_disable() is fixme!");
 }
 
 void check_assertion_disable() {
   no_assertion_text_disable();
-  no_assertion_exception_disable();
-  assertion_exception_disable();
   assertion_text_disable();
   fixme_disable();
 }
 #undef LEMON_DISABLE_ASSERTS
 
-
-#define LEMON_ASSERT_ERROR
-#include <lemon/assert.h>
-
-void no_assertion_text_error() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_error() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_error() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_error() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_error() {
-  LEMON_FIXME("fixme_error() is fixme!");
-}
-
-void check_assertion_error() {
-  no_assertion_text_error();
-  no_assertion_exception_error();
-  try {
-    assertion_exception_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    assertion_text_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    fixme_error();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-}
-#undef LEMON_ASSERT_ERROR
-
-#define LEMON_ASSERT_EXCEPTION
-#include <lemon/assert.h>
-
-void no_assertion_text_exception() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_exception() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_exception() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_exception() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_exception() {
-  LEMON_FIXME("fixme_exception() is fixme!");
-}
-
-void check_assertion_exception() {
-  no_assertion_text_exception();
-  no_assertion_exception_exception();
-  try {
-    assertion_exception_exception();
-    check(false, "Assertion error");
-  } catch (const Exception& e) {
-  }
-
-  try {
-    assertion_text_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    assertion_text_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-
-  try {
-    fixme_exception();
-    check(false, "Assertion error");
-  } catch (const AssertionFailedError& e) {
-  }
-}
-#undef LEMON_ASSERT_EXCEPTION
-
-#define LEMON_ASSERT_LOG
-
-#include <lemon/assert.h>
-
-void no_assertion_text_log() {
-  LEMON_ASSERT(true, "This is a fault message");
-}
-
-void no_assertion_exception_log() {
-  LEMON_ASSERT(true, Exception());
-}
-
-void assertion_text_log() {
-  LEMON_ASSERT(false, "This is a fault message");
-}
-
-void assertion_exception_log() {
-  LEMON_ASSERT(false, Exception());
-}
-
-void fixme_log() {
-  LEMON_FIXME("fixme_log() is fixme!");
-}
-
-void check_assertion_log() {
-  no_assertion_text_log();
-  no_assertion_exception_log();
-  std::cerr << "The next 3 failure messages are expected: " << std::endl;
-  assertion_exception_log();
-  assertion_text_log();
-  fixme_log();
-  std::cerr << "End of expected error messages" << std::endl;
-}
-#undef LEMON_ASSERT_LOG
-
 #define LEMON_ASSERT_CUSTOM
 
 static int cnt = 0;
@@ -206,17 +62,6 @@
   ++cnt;
 }
 
-void my_assert_handler(const char*, int, const char*, 
-		       const std::exception&, const char*) {
-  ++cnt;
-}
-
-void my_assert_handler(const char*, int, const char*, 
-		       const std::string&, const char*) {
-  ++cnt;
-}
-
-
 #define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
 #include <lemon/assert.h>
 
@@ -224,29 +69,19 @@
   LEMON_ASSERT(true, "This is a fault message");
 }
 
-void no_assertion_exception_custom() {
-  LEMON_ASSERT(true, Exception());
-}
-
 void assertion_text_custom() {
   LEMON_ASSERT(false, "This is a fault message");
 }
 
-void assertion_exception_custom() {
-  LEMON_ASSERT(false, Exception());
-}
-
 void fixme_custom() {
   LEMON_FIXME("fixme_custom() is fixme!");
 }
 
 void check_assertion_custom() {
   no_assertion_text_custom();
-  no_assertion_exception_custom();
-  assertion_exception_custom();
   assertion_text_custom();
   fixme_custom();
-  check(cnt == 3, "The custom assert handler does not work");
+  check(cnt == 2, "The custom assert handler does not work");
 }
 
 #undef LEMON_ASSERT_CUSTOM
@@ -254,9 +89,6 @@
 
 int main() {
   check_assertion_disable();
-  check_assertion_error();
-  check_assertion_exception();
-  check_assertion_log();
   check_assertion_custom();
 
   return 0;
diff -r 8899d1891a3c -r ae7785fe8431 test/time_measure_test.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/time_measure_test.cc	Sat Apr 12 20:38:51 2008 +0100
@@ -0,0 +1,63 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/time_measure.h>
+
+///\file \brief Test cases for time_measure.h
+///
+///\todo To be extended
+
+
+using namespace lemon;
+
+void f() 
+{
+  double d=0;
+  for(int i=0;i<1000;i++)
+    d+=0.1;
+}
+
+void g() 
+{
+  static Timer T;
+  
+  for(int i=0;i<1000;i++)
+    TimeStamp x(T);
+}
+
+int main()
+{
+  Timer T;
+  unsigned int n;
+  for(n=0;T.realTime()<1.0;n++) ;
+  std::cout << T << " (" << n << " time queries)\n";
+  T.restart();
+  while(T.realTime()<2.0) ;
+  std::cout << T << '\n';
+  TimeStamp full;
+  TimeStamp t;
+  t=runningTimeTest(f,1,&n,&full);
+  std::cout << t << " (" << n << " tests)\n";
+  std::cout << "Total: " << full << "\n";
+  
+  t=runningTimeTest(g,1,&n,&full);
+  std::cout << t << " (" << n << " tests)\n";
+  std::cout << "Total: " << full << "\n";
+  
+  return 0;
+}