16 #ifndef __OMNETPP_SIMTIME_H
17 #define __OMNETPP_SIMTIME_H
22 #include "platdep/intlimits.h"
23 #include "simkerneldefs.h"
30 #define INT64_MAX_DBL 9.22337203685e18
72 static int64_t dscale;
74 static double invfscale;
75 static int64_t maxseconds;
78 static const int SCALEEXP_UNINITIALIZED = 0xffff;
89 static void resetScale() {scaleexp = SCALEEXP_UNINITIALIZED;}
92 template<
typename T>
void assertInited(T d) {
if (scaleexp==SCALEEXP_UNINITIALIZED) initError(d);}
93 [[noreturn]]
void initError(
double d);
95 bool haveSameSign(int64_t a, int64_t b) {
return (a^b) >= 0; }
97 void fromInt64WithUnit(int64_t d,
SimTimeUnit unit);
98 void fromUint64WithUnit(uint64_t d,
SimTimeUnit unit);
100 int64_t toInt64(
double d) {
102 if (
fabs(d) <= INT64_MAX_DBL)
108 int64_t fromUint64(uint64_t u) {
109 if (u > (uint64_t)INT64_MAX)
114 void setSeconds(int64_t sec) {
115 if (sec > maxseconds || sec < -maxseconds)
116 rangeErrorSeconds(sec);
120 void setSecondsU(uint64_t sec) {
121 if (sec > (uint64_t)maxseconds)
122 rangeErrorSeconds(sec);
126 void checkedAdd(
const SimTime& x) {
128 bool sameSign = haveSameSign(t, x.t);
130 if (sameSign && !haveSameSign(t, x.t))
134 void checkedSub(
const SimTime& x) {
136 bool differentSign = !haveSameSign(t, x.t);
138 if (differentSign && haveSameSign(t, x.t))
139 overflowSubtracting(x);
142 void checkedMul(int64_t x);
144 [[noreturn]]
void rangeErrorInt64(
double i64);
145 [[noreturn]]
void rangeErrorSeconds(int64_t x);
146 [[noreturn]]
void overflowAdding(
const SimTime& x);
147 [[noreturn]]
void overflowSubtracting(
const SimTime& x);
148 [[noreturn]]
void overflowNegating();
152 std::string format(
int prec=getScaleExp(),
const char *decimalSep=
".",
const char *digitSep=
"",
bool addUnits=
false,
const char *beforeUnit=
nullptr,
const char *afterUnit=
nullptr)
const;
176 SimTime(
long d) {operator=(d);}
177 SimTime(
long long d) {operator=(d);}
178 SimTime(
unsigned short d) {operator=(d);}
179 SimTime(
unsigned int d) {operator=(d);}
180 SimTime(
unsigned long d) {operator=(d);}
181 SimTime(
unsigned long long d) {operator=(d);}
220 SimTime(
long d,
SimTimeUnit unit) {fromInt64WithUnit(d, unit);}
221 SimTime(
long long d,
SimTimeUnit unit) {fromInt64WithUnit(d, unit);}
222 SimTime(
unsigned short d,
SimTimeUnit unit) {fromUint64WithUnit(d, unit);}
223 SimTime(
unsigned int d,
SimTimeUnit unit) {fromUint64WithUnit(d, unit);}
224 SimTime(
unsigned long d,
SimTimeUnit unit) {fromUint64WithUnit(d, unit);}
225 SimTime(
unsigned long long d,
SimTimeUnit unit) {fromUint64WithUnit(d, unit);}
237 SimTime& operator=(
double d) {assertInited(d); t=toInt64(fscale*d);
return *
this;}
238 SimTime& operator=(
short d) {assertInited(d); setSeconds(d);
return *
this;}
239 SimTime& operator=(
int d) {assertInited(d); setSeconds(d);
return *
this;}
240 SimTime& operator=(
long d) {assertInited(d); setSeconds(d);
return *
this;}
241 SimTime& operator=(
long long d) {assertInited(d); setSeconds(d);
return *
this;}
242 SimTime& operator=(
unsigned short d) {assertInited(d); setSecondsU(d);
return *
this;}
243 SimTime& operator=(
unsigned int d) {assertInited(d); setSecondsU(d);
return *
this;}
244 SimTime& operator=(
unsigned long d) {assertInited(d); setSecondsU(d);
return *
this;}
245 SimTime& operator=(
unsigned long long d) {assertInited(d); setSecondsU(d);
return *
this;}
247 bool operator==(
const SimTime& x)
const {
return t==x.t;}
248 bool operator!=(
const SimTime& x)
const {
return t!=x.t;}
249 bool operator< (
const SimTime& x)
const {
return t<x.t;}
250 bool operator> (
const SimTime& x)
const {
return t>x.t;}
251 bool operator<=(
const SimTime& x)
const {
return t<=x.t;}
252 bool operator>=(
const SimTime& x)
const {
return t>=x.t;}
254 SimTime operator-()
const {SimTime x; x.t = -t;
if (x.t==INT64_MIN) x.overflowNegating();
return x;}
256 const SimTime& operator+=(
const SimTime& x) {checkedAdd(x);
return *
this;}
257 const SimTime& operator-=(
const SimTime& x) {checkedSub(x);
return *
this;}
258 friend const SimTime operator+(
const SimTime& x,
const SimTime& y) {
return SimTime(x)+=y; }
259 friend const SimTime operator-(
const SimTime& x,
const SimTime& y) {
return SimTime(x)-=y; }
261 const SimTime& operator*=(
double d) {t=toInt64(t*d);
return *
this;}
262 const SimTime& operator*=(
short d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
263 const SimTime& operator*=(
int d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
264 const SimTime& operator*=(
long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
265 const SimTime& operator*=(
long long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
266 const SimTime& operator*=(
unsigned short d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
267 const SimTime& operator*=(
unsigned int d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
268 const SimTime& operator*=(
unsigned long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
269 const SimTime& operator*=(
unsigned long long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
270 const SimTime& operator*=(
const cPar& p);
272 const SimTime& operator/=(
double d) {t=toInt64(t/d);
return *
this;}
273 const SimTime& operator/=(
short d) {t/=d;
return *
this;}
274 const SimTime& operator/=(
int d) {t/=d;
return *
this;}
275 const SimTime& operator/=(
long d) {t/=d;
return *
this;}
276 const SimTime& operator/=(
long long d) {t/=d;
return *
this;}
277 const SimTime& operator/=(
unsigned short d) {t/=d;
return *
this;}
278 const SimTime& operator/=(
unsigned int d) {t/=d;
return *
this;}
279 const SimTime& operator/=(
unsigned long d) {t/=d;
return *
this;}
280 const SimTime& operator/=(
unsigned long long d) {t/=d;
return *
this;}
281 const SimTime& operator/=(
const cPar& p);
283 friend const SimTime operator*(
const SimTime& x,
double d) {
return SimTime(x)*=d; }
284 friend const SimTime operator*(
const SimTime& x,
short d) {
return SimTime(x)*=d; }
285 friend const SimTime operator*(
const SimTime& x,
int d) {
return SimTime(x)*=d; }
286 friend const SimTime operator*(
const SimTime& x,
long d) {
return SimTime(x)*=d; }
287 friend const SimTime operator*(
const SimTime& x,
long long d) {
return SimTime(x)*=d; }
288 friend const SimTime operator*(
const SimTime& x,
unsigned short d) {
return SimTime(x)*=d; }
289 friend const SimTime operator*(
const SimTime& x,
unsigned int d) {
return SimTime(x)*=d; }
290 friend const SimTime operator*(
const SimTime& x,
unsigned long d) {
return SimTime(x)*=d; }
291 friend const SimTime operator*(
const SimTime& x,
unsigned long long d) {
return SimTime(x)*=d; }
292 friend const SimTime operator*(
const SimTime& x,
const cPar& p) {
return SimTime(x)*=p; }
294 friend const SimTime operator*(
double d,
const SimTime& x) {
return SimTime(x)*=d; }
295 friend const SimTime operator*(
short d,
const SimTime& x) {
return SimTime(x)*=d; }
296 friend const SimTime operator*(
int d,
const SimTime& x) {
return SimTime(x)*=d; }
297 friend const SimTime operator*(
long d,
const SimTime& x) {
return SimTime(x)*=d; }
298 friend const SimTime operator*(
long long d,
const SimTime& x) {
return SimTime(x)*=d; }
299 friend const SimTime operator*(
unsigned short d,
const SimTime& x) {
return SimTime(x)*=d; }
300 friend const SimTime operator*(
unsigned int d,
const SimTime& x) {
return SimTime(x)*=d; }
301 friend const SimTime operator*(
unsigned long d,
const SimTime& x) {
return SimTime(x)*=d; }
302 friend const SimTime operator*(
unsigned long long d,
const SimTime& x) {
return SimTime(x)*=d; }
303 friend const SimTime operator*(
const cPar& p,
const SimTime& x) {
return SimTime(x)*=p; }
305 friend const SimTime operator/(
const SimTime& x,
double d) {
return SimTime(x)/=d; }
306 friend const SimTime operator/(
const SimTime& x,
short d) {
return SimTime(x)/=d; }
307 friend const SimTime operator/(
const SimTime& x,
int d) {
return SimTime(x)/=d; }
308 friend const SimTime operator/(
const SimTime& x,
long d) {
return SimTime(x)/=d; }
309 friend const SimTime operator/(
const SimTime& x,
long long d) {
return SimTime(x)/=d; }
310 friend const SimTime operator/(
const SimTime& x,
unsigned short d) {
return SimTime(x)/=d; }
311 friend const SimTime operator/(
const SimTime& x,
unsigned int d) {
return SimTime(x)/=d; }
312 friend const SimTime operator/(
const SimTime& x,
unsigned long d) {
return SimTime(x)/=d; }
313 friend const SimTime operator/(
const SimTime& x,
unsigned long long d) {
return SimTime(x)/=d; }
314 friend const SimTime operator/(
const SimTime& x,
const cPar& p) {
return SimTime(x)/=p; }
316 friend double operator/(
const SimTime& x,
const SimTime& y) {
return (
double)x.raw() / (double)y.raw(); }
318 friend double operator/(
double x,
const SimTime& y) {
return x / y.dbl(); }
319 friend double operator/(
short x,
const SimTime& y) {
return (
long long)x / y; }
320 friend double operator/(
int x,
const SimTime& y) {
return (
long long)x / y; }
321 friend double operator/(
long x,
const SimTime& y) {
return (
long long)x / y; }
322 friend SIM_API
double operator/(
long long x,
const SimTime& y);
323 friend double operator/(
unsigned short x,
const SimTime& y) {
return (
unsigned long long)x / y; }
324 friend double operator/(
unsigned int x,
const SimTime& y) {
return (
unsigned long long)x / y; }
325 friend double operator/(
unsigned long x,
const SimTime& y) {
return (
unsigned long long)x / y; }
326 friend SIM_API
double operator/(
unsigned long long x,
const SimTime& y);
327 friend SIM_API
double operator/(
const cPar& p,
const SimTime& x);
346 double dbl()
const {
return t*invfscale;}
396 std::string
str()
const {
char buf[64];
return str(buf);}
405 char *
str(
char *buf)
const {
char *endp;
return SimTime::ttoa(buf, t, getScaleExp(), endp);}
413 std::string ustr()
const;
426 int64_t
raw()
const {
return t;}
468 static void setScaleExp(
int e);
475 static const SimTime parse(
const char *s);
486 static const SimTime parse(
const char *s,
const char *&endp);
497 static char *ttoa(
char *buf, int64_t t,
int scaleexp,
char *&endp);
501 inline std::ostream& operator<<(std::ostream& os,
const SimTime& x)
503 char buf[64];
char *endp;