#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>
#endif
#if defined(BOOST_CHRONO_WINDOWS_API)
# include <windows.h>
#endif
#if defined(BOOST_CHRONO_WINDOWS_API)
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
namespace timeval_demo
{
class xtime {
private:
long tv_sec;
long tv_usec;
void fixup() {
if (tv_usec < 0) {
tv_usec += 1000000;
--tv_sec;
}
}
public:
explicit xtime(long sec, long usec) {
tv_sec = sec;
tv_usec = usec;
if (tv_usec < 0 || tv_usec >= 1000000) {
tv_sec += tv_usec / 1000000;
tv_usec %= 1000000;
fixup();
}
}
explicit xtime(long long usec)
{
tv_usec = static_cast<long>(usec % 1000000);
tv_sec = static_cast<long>(usec / 1000000);
fixup();
}
operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
xtime& operator += (xtime rhs) {
tv_sec += rhs.tv_sec;
tv_usec += rhs.tv_usec;
if (tv_usec >= 1000000) {
tv_usec -= 1000000;
++tv_sec;
}
return *this;
}
xtime& operator -= (xtime rhs) {
tv_sec -= rhs.tv_sec;
tv_usec -= rhs.tv_usec;
fixup();
return *this;
}
xtime& operator %= (xtime rhs) {
long long t = tv_sec * 1000000 + tv_usec;
long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
t %= r;
tv_sec = static_cast<long>(t / 1000000);
tv_usec = static_cast<long>(t % 1000000);
fixup();
return *this;
}
friend xtime operator+(xtime x, xtime y) {return x += y;}
friend xtime operator-(xtime x, xtime y) {return x -= y;}
friend xtime operator%(xtime x, xtime y) {return x %= y;}
friend bool operator==(xtime x, xtime y)
{ return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
friend bool operator<(xtime x, xtime y) {
if (x.tv_sec == y.tv_sec)
return (x.tv_usec < y.tv_usec);
return (x.tv_sec < y.tv_sec);
}
friend bool operator!=(xtime x, xtime y) { return !(x == y); }
friend bool operator> (xtime x, xtime y) { return y < x; }
friend bool operator<=(xtime x, xtime y) { return !(y < x); }
friend bool operator>=(xtime x, xtime y) { return !(x < y); }
friend std::ostream& operator<<(std::ostream& os, xtime x)
{return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
};
class xtime_clock
{
public:
typedef xtime rep;
typedef boost::micro period;
typedef boost::chrono::duration<rep, period> duration;
typedef boost::chrono::time_point<xtime_clock> time_point;
static time_point now();
};
xtime_clock::time_point
xtime_clock::now()
{
#if defined(BOOST_CHRONO_WINDOWS_API)
timeval tv;
gettimeofday(&tv, 0);
xtime xt( tv.tv_sec, tv.tv_usec);
return time_point(duration(xt));
#elif defined(BOOST_CHRONO_MAC_API)
timeval tv;
gettimeofday(&tv, 0);
xtime xt( tv.tv_sec, tv.tv_usec);
return time_point(duration(xt));
#elif defined(BOOST_CHRONO_POSIX_API)
timespec ts;
::clock_gettime( CLOCK_REALTIME, &ts );
xtime xt( ts.tv_sec, ts.tv_nsec/1000);
return time_point(duration(xt));
#endif
}
void test_xtime_clock()
{
using namespace boost::chrono;
std::cout << "timeval_demo system clock test\n";
std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
xtime_clock::duration delay(milliseconds(5));
xtime_clock::time_point start = xtime_clock::now();
while (xtime_clock::now() - start <= delay)
{
}
xtime_clock::time_point stop = xtime_clock::now();
xtime_clock::duration elapsed = stop - start;
std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
}
}
int main()
{
timeval_demo::test_xtime_clock();
return 0;
}