34 #ifndef ROSTIME_IMPL_DURATION_H_INCLUDED
35 #define ROSTIME_IMPL_DURATION_H_INCLUDED
42 #include <boost/date_time/posix_time/posix_time_types.hpp>
43 #include <boost/math/special_functions/round.hpp>
51 : sec(_sec), nsec(_nsec)
57 T& DurationBase<T>::fromSec(
double d)
59 if (!std::isfinite(d))
60 throw std::runtime_error(
"Duration has to be finite.");
61 constexpr
double minInt64AsDouble =
static_cast<double>(std::numeric_limits<int64_t>::min());
62 constexpr
double maxInt64AsDouble =
static_cast<double>(std::numeric_limits<int64_t>::max());
63 if (d <= minInt64AsDouble || d >= maxInt64AsDouble)
64 throw std::runtime_error(
"Duration is out of 64-bit integer range");
65 int64_t sec64 =
static_cast<int64_t
>(floor(d));
66 if (sec64 < std::numeric_limits<int32_t>::min() || sec64 > std::numeric_limits<int32_t>::max())
67 throw std::runtime_error(
"Duration is out of dual 32-bit range");
68 sec =
static_cast<int32_t
>(sec64);
69 nsec =
static_cast<int32_t
>(boost::math::round((d - sec) * 1e9));
70 int32_t rollover = nsec / 1000000000ul;
73 return *
static_cast<T*
>(
this);
77 T& DurationBase<T>::fromNSec(int64_t t)
79 int64_t sec64 = t / 1000000000LL;
80 if (sec64 < std::numeric_limits<int32_t>::min() || sec64 > std::numeric_limits<int32_t>::max())
81 throw std::runtime_error(
"Duration is out of dual 32-bit range");
82 sec =
static_cast<int32_t
>(sec64);
83 nsec =
static_cast<int32_t
>(t % 1000000000LL);
87 return *
static_cast<T*
>(
this);
94 return t.
fromNSec(toNSec() + rhs.toNSec());
100 return T(toSec() * scale);
104 T DurationBase<T>::operator-(
const T &rhs)
const
107 return t.fromNSec(toNSec() - rhs.toNSec());
121 return *
static_cast<T*
>(
this);
128 return *
static_cast<T*
>(
this);
134 fromSec(toSec() * scale);
135 return *
static_cast<T*
>(
this);
143 else if (sec == rhs.sec && nsec < rhs.nsec)
153 else if (sec == rhs.sec && nsec > rhs.nsec)
163 else if (sec == rhs.sec && nsec <= rhs.nsec)
173 else if (sec == rhs.sec && nsec >= rhs.nsec)
181 return sec == rhs.
sec && nsec == rhs.nsec;
187 return sec == 0 && nsec == 0;
191 boost::posix_time::time_duration
195 #if defined(BOOST_DATE_TIME_HAS_NANOSECONDS)
196 return bt::seconds(sec) + bt::nanoseconds(nsec);
198 return bt::seconds(sec) + bt::microseconds(nsec/1000);