00001 // Copyright (C) 2001 Petter Urkedal (petter.urkedal@matfys.lth.se) 00002 // 00003 // This file is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This file is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software library without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to 00021 // produce an executable, this file does not by itself cause the 00022 // resulting executable to be covered by the GNU General Public 00023 // License. This exception does not however invalidate any other 00024 // reasons why the executable file might be covered by the GNU General 00025 // Public License. 00026 // 00027 // $Id: stopwatch.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $ 00028 00029 00030 #include <stdexcept> 00031 #include <more/sys/time.h> 00032 00033 namespace more { 00034 namespace diag { 00035 00036 //! Class for timing program execution. 00037 class stopwatch 00038 { 00039 bool run; 00040 mutable clock_t t0; 00041 mutable double accum; 00042 public: 00043 /** Construct a stopwatch initialized to t=0. */ 00044 stopwatch() 00045 : run(false), accum(0) {} 00046 /** Construct a stopwatch initialized to the time \a t seconds. */ 00047 stopwatch(double t) 00048 : run(false), accum(t) {} 00049 00050 /** Start a stopwatch which is not already running. 00051 The stopwatch will continue from its current value. */ 00052 void start() 00053 { 00054 if(run) throw std::logic_error 00055 ("stopwatch::start(): Stopwatch is already running."); 00056 t0 = clock(); 00057 run = true; 00058 } 00059 00060 /** Stop a running stopwatch. */ 00061 void stop() 00062 { 00063 if(!run) throw std::logic_error 00064 ("stopwatch::stop(): Stopwatch is not running."); 00065 accum += double(clock()-t0)/CLOCKS_PER_SEC; 00066 run = false; 00067 } 00068 00069 /** Reset the stopwatch. 00070 If the stopwatch is running, it will continue running from t=0. */ 00071 void reset() { accum = 0; if (run) t0=clock(); } 00072 00073 //! Start a stopwatch, which is not running, from t=0. 00074 void restart() { accum = 0; start(); } 00075 00076 //! Conversion to double gives the current time in second. 00077 operator double() const { if (run) flush(); return accum; } 00078 00079 //! Assign a time of \a t seconds to the stopwatch. 00080 stopwatch& operator=(double t) { t0=clock(); accum=t; return *this; } 00081 00082 //! True iff the stopwatch is running. 00083 bool running() const { return run; } 00084 00085 void flush() const 00086 { 00087 if (!run) 00088 throw std::logic_error("more::stopwatch::flush(): " 00089 "Stopwatch is not running."); 00090 clock_t t1 = clock(); 00091 accum += double(t1-t0)/CLOCKS_PER_SEC; 00092 t0 = t1; 00093 } 00094 }; 00095 00096 inline std::ostream& 00097 operator<<(std::ostream& out, const stopwatch& sw) 00098 { 00099 sys::print_time_nicely(out, sw); return out; 00100 } 00101 00102 }}