#define _CRT_SECURE_NO_WARNINGS
#include <boost/chrono/chrono.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
#if defined(BOOST_CHRONO_MAC_API)
#include <sys/time.h>
#include <mach/mach_time.h>
#endif
#if defined(BOOST_CHRONO_WINDOWS_API)
#include <windows.h>
namespace
{
#if defined UNDER_CE || BOOST_PLAT_WINDOWS_RUNTIME
struct timeval {
long tv_sec;
long tv_usec;
};
#endif
int gettimeofday(struct timeval * tp, void *)
{
FILETIME ft;
#if defined(UNDER_CE)
SYSTEMTIME st;
::GetSystemTime( &st );
::SystemTimeToFileTime( &st, &ft );
#else
::GetSystemTimeAsFileTime( &ft ); #endif
long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300
t -= 116444736000000000LL;
# else
t -= 116444736000000000;
# endif
t /= 10; tp->tv_sec = static_cast<long>( t / 1000000UL);
tp->tv_usec = static_cast<long>( t % 1000000UL);
return 0;
}
}
#endif
using namespace boost::chrono;
namespace runtime_resolution
{
class duration
{
public:
typedef long long rep;
private:
rep rep_;
static const double ticks_per_nanosecond;
public:
typedef boost::chrono::duration<double, boost::nano> tonanosec;
duration() {} explicit duration(const rep& r) : rep_(r) {}
explicit duration(const tonanosec& d)
: rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
tonanosec convert_to_nanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
rep count() const {return rep_;}
duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
duration operator+() const {return *this;}
duration operator-() const {return duration(-rep_);}
duration& operator++() {++rep_; return *this;}
duration operator++(int) {return duration(rep_++);}
duration& operator--() {--rep_; return *this;}
duration operator--(int) {return duration(rep_--);}
friend duration operator+(duration x, duration y) {return x += y;}
friend duration operator-(duration x, duration y) {return x -= y;}
friend duration operator*(duration x, rep y) {return x *= y;}
friend duration operator*(rep x, duration y) {return y *= x;}
friend duration operator/(duration x, rep y) {return x /= y;}
friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
friend bool operator!=(duration x, duration y) {return !(x == y);}
friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
friend bool operator<=(duration x, duration y) {return !(y < x);}
friend bool operator> (duration x, duration y) {return y < x;}
friend bool operator>=(duration x, duration y) {return !(x < y);}
};
static
double
init_duration()
{
#if defined(BOOST_CHRONO_WINDOWS_API)
return static_cast<double>(1) / 1000; #elif defined(BOOST_CHRONO_MAC_API)
mach_timebase_info_data_t MachInfo;
mach_timebase_info(&MachInfo);
return static_cast<double>(MachInfo.denom) / MachInfo.numer;
#elif defined(BOOST_CHRONO_POSIX_API)
return static_cast<double>(1) / 1000;
#endif
}
const double duration::ticks_per_nanosecond = init_duration();
class clock;
class time_point
{
public:
typedef runtime_resolution::clock clock;
typedef long long rep;
private:
rep rep_;
rep count() const {return rep_;}
public:
time_point() : rep_(0) {}
explicit time_point(const duration& d)
: rep_(d.count()) {}
time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
friend time_point operator+(time_point x, duration y) {return x += y;}
friend time_point operator+(duration x, time_point y) {return y += x;}
friend time_point operator-(time_point x, duration y) {return x -= y;}
friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
};
class clock
{
public:
typedef runtime_resolution::duration::rep rep;
typedef runtime_resolution::duration duration;
typedef runtime_resolution::time_point time_point;
static time_point now()
{
#if defined(BOOST_CHRONO_WINDOWS_API)
timeval tv;
gettimeofday( &tv, 0 );
return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
#elif defined(BOOST_CHRONO_MAC_API)
timeval tv;
gettimeofday( &tv, 0 );
return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
#elif defined(BOOST_CHRONO_POSIX_API)
timespec ts;
::clock_gettime( CLOCK_REALTIME, &ts );
return time_point(duration((static_cast<rep>(ts.tv_sec)<<32) | ts.tv_nsec/1000));
#endif
}
};
void test()
{
std::cout << "runtime_resolution test\n";
clock::duration delay(boost::chrono::milliseconds(5));
clock::time_point start = clock::now();
while (clock::now() - start <= delay)
;
clock::time_point stop = clock::now();
clock::duration elapsed = stop - start;
std::cout << "paused " <<
boost::chrono::nanoseconds(
boost::chrono::duration_cast<boost::chrono::nanoseconds>( elapsed.convert_to_nanosec() )).count()
<< " nanoseconds\n";
}
}
int main()
{
runtime_resolution::test();
return 0;
}