libmoost
/home/mhx/git/github/libmoost/include/moost/utils/stopwatch.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00035 #ifndef MOOST_UTILS_STOPWATCH_HPP__
00036 #define MOOST_UTILS_STOPWATCH_HPP__
00037 
00038 #include <boost/date_time/posix_time/posix_time.hpp>
00039 #include <boost/cstdint.hpp>
00040 #include <boost/noncopyable.hpp>
00041 
00042 namespace moost { namespace utils {
00043 
00048    class stopwatch : boost::noncopyable
00049    {
00050    public:
00051 
00052       typedef boost::int64_t elapsed_t;
00053 
00054       stopwatch()
00055       {
00056          restart();
00057       }
00058 
00059       void restart()
00060       {
00061          start_ = boost::posix_time::microsec_clock::universal_time();
00062       }
00063 
00064       elapsed_t elapsed_ns() const // nanosecs
00065       {
00066          boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
00067          return (now - start_).total_nanoseconds();
00068       }
00069 
00070       elapsed_t elapsed_us() const // microsecs (default)
00071       {
00072          boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
00073          return (now - start_).total_microseconds();
00074       }
00075 
00076       elapsed_t elapsed_ms() const // millisecs
00077       {
00078          boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
00079          return (now - start_).total_milliseconds();
00080       }
00081 
00082       elapsed_t elapsed_secs() const // secs
00083       {
00084          boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
00085          return (now - start_).total_seconds();
00086       }
00087 
00088       elapsed_t elapsed() const
00089       {
00090          return elapsed_us();
00091       }
00092 
00093    private:
00094       boost::posix_time::ptime start_;
00095    };
00096 
00101    class scoped_stopwatch : boost::noncopyable
00102    {
00103    public:
00104       enum granularity
00105       {
00106          nanosecs, microsecs, millisecs, secs
00107       };
00108 
00109       typedef stopwatch::elapsed_t elapsed_t;
00110 
00111       scoped_stopwatch(
00112          elapsed_t & future, // This is a future, which will be assigned elapsed on destruction
00113          granularity const g = microsecs, // This is the granularity of elapsed (default is microsecs)
00114          bool const a = false // If true add elapsed to future else assign elapsed to future
00115          )
00116          : future_(future), granularity_(g), accumulate_(a)
00117       {
00118       }
00119 
00120       ~scoped_stopwatch()
00121       {
00122          elapsed_t e;
00123 
00124          switch(granularity_)
00125          {
00126          case secs:
00127             e = sw_.elapsed_secs();
00128             break;
00129          case millisecs:
00130             e = sw_.elapsed_ms();
00131             break;
00132          case microsecs:
00133             e = sw_.elapsed_us();
00134             break;
00135          case nanosecs:
00136             e = sw_.elapsed_ns();
00137             break;
00138          default:
00139             e = sw_.elapsed();
00140             break;
00141          }
00142 
00143          future_ = e + (accumulate_ ? future_ : 0);
00144       }
00145 
00146    private:
00147       stopwatch sw_;
00148       elapsed_t & future_;
00149       granularity const granularity_;
00150       bool const accumulate_;
00151    };
00152 
00153 }}
00154 
00155 #endif // MOOST_UTILS_STOPWATCH_HPP__