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 int64_t toInt64(
double i64) {
98 i64 =
floor(i64 + 0.5);
99 if (
fabs(i64) <= INT64_MAX_DBL)
102 rangeErrorInt64(i64);
105 void setSeconds(int64_t sec) {
106 if (sec > maxseconds || sec < -maxseconds)
107 rangeErrorSeconds(sec);
111 void setSecondsU(uint64_t sec) {
112 if (sec > maxseconds)
113 rangeErrorSeconds(sec);
117 void checkedAdd(
const SimTime& x) {
119 bool sameSign = haveSameSign(t, x.t);
121 if (sameSign && !haveSameSign(t, x.t))
125 void checkedSub(
const SimTime& x) {
127 bool differentSign = !haveSameSign(t, x.t);
129 if (differentSign && haveSameSign(t, x.t))
130 overflowSubtracting(x);
133 void checkedMul(int64_t x);
135 [[noreturn]]
void rangeErrorInt64(
double i64);
136 [[noreturn]]
void rangeErrorSeconds(int64_t x);
137 [[noreturn]]
void overflowAdding(
const SimTime& x);
138 [[noreturn]]
void overflowSubtracting(
const SimTime& x);
139 [[noreturn]]
void overflowNegating();
143 std::string format(
int prec=getScaleExp(),
const char *decimalSep=
".",
const char *digitSep=
"",
bool addUnits=
false,
const char *beforeUnit=
nullptr,
const char *afterUnit=
nullptr)
const;
198 SimTime& operator=(
double d) {assertInited(d); t=toInt64(fscale*d);
return *
this;}
199 SimTime& operator=(
short d) {assertInited(d); setSeconds(d);
return *
this;}
200 SimTime& operator=(
int d) {assertInited(d); setSeconds(d);
return *
this;}
201 SimTime& operator=(
long d) {assertInited(d); setSeconds(d);
return *
this;}
202 SimTime& operator=(
long long d) {assertInited(d); setSeconds(d);
return *
this;}
203 SimTime& operator=(
unsigned short d) {assertInited(d); setSecondsU(d);
return *
this;}
204 SimTime& operator=(
unsigned int d) {assertInited(d); setSecondsU(d);
return *
this;}
205 SimTime& operator=(
unsigned long d) {assertInited(d); setSecondsU(d);
return *
this;}
206 SimTime& operator=(
unsigned long long d) {assertInited(d); setSecondsU(d);
return *
this;}
208 bool operator==(
const SimTime& x)
const {
return t==x.t;}
209 bool operator!=(
const SimTime& x)
const {
return t!=x.t;}
210 bool operator< (
const SimTime& x)
const {
return t<x.t;}
211 bool operator> (
const SimTime& x)
const {
return t>x.t;}
212 bool operator<=(
const SimTime& x)
const {
return t<=x.t;}
213 bool operator>=(
const SimTime& x)
const {
return t>=x.t;}
215 SimTime operator-()
const {SimTime x; x.t = -t;
if (x.t==INT64_MIN) x.overflowNegating();
return x;}
217 const SimTime& operator+=(
const SimTime& x) {checkedAdd(x);
return *
this;}
218 const SimTime& operator-=(
const SimTime& x) {checkedSub(x);
return *
this;}
219 friend const SimTime operator+(
const SimTime& x,
const SimTime& y) {
return SimTime(x)+=y; }
220 friend const SimTime operator-(
const SimTime& x,
const SimTime& y) {
return SimTime(x)-=y; }
222 const SimTime& operator*=(
double d) {t=toInt64(t*d);
return *
this;}
223 const SimTime& operator*=(
short d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
224 const SimTime& operator*=(
int d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
225 const SimTime& operator*=(
long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
226 const SimTime& operator*=(
long long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
227 const SimTime& operator*=(
unsigned short d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
228 const SimTime& operator*=(
unsigned int d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
229 const SimTime& operator*=(
unsigned long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
230 const SimTime& operator*=(
unsigned long long d) {
if (checkmul) checkedMul(d);
else t*=d;
return *
this;}
231 const SimTime& operator*=(
const cPar& p);
233 const SimTime& operator/=(
double d) {t=toInt64(t/d);
return *
this;}
234 const SimTime& operator/=(
short d) {t/=d;
return *
this;}
235 const SimTime& operator/=(
int d) {t/=d;
return *
this;}
236 const SimTime& operator/=(
long d) {t/=d;
return *
this;}
237 const SimTime& operator/=(
long long d) {t/=d;
return *
this;}
238 const SimTime& operator/=(
unsigned short d) {t/=d;
return *
this;}
239 const SimTime& operator/=(
unsigned int d) {t/=d;
return *
this;}
240 const SimTime& operator/=(
unsigned long d) {t/=d;
return *
this;}
241 const SimTime& operator/=(
unsigned long long d) {t/=d;
return *
this;}
242 const SimTime& operator/=(
const cPar& p);
244 friend const SimTime operator*(
const SimTime& x,
double d) {
return SimTime(x)*=d; }
245 friend const SimTime operator*(
const SimTime& x,
short d) {
return SimTime(x)*=d; }
246 friend const SimTime operator*(
const SimTime& x,
int d) {
return SimTime(x)*=d; }
247 friend const SimTime operator*(
const SimTime& x,
long d) {
return SimTime(x)*=d; }
248 friend const SimTime operator*(
const SimTime& x,
long long d) {
return SimTime(x)*=d; }
249 friend const SimTime operator*(
const SimTime& x,
unsigned short d) {
return SimTime(x)*=d; }
250 friend const SimTime operator*(
const SimTime& x,
unsigned int d) {
return SimTime(x)*=d; }
251 friend const SimTime operator*(
const SimTime& x,
unsigned long d) {
return SimTime(x)*=d; }
252 friend const SimTime operator*(
const SimTime& x,
unsigned long long d) {
return SimTime(x)*=d; }
253 friend const SimTime operator*(
const SimTime& x,
const cPar& p) {
return SimTime(x)*=p; }
255 friend const SimTime operator*(
double d,
const SimTime& x) {
return SimTime(x)*=d; }
256 friend const SimTime operator*(
short d,
const SimTime& x) {
return SimTime(x)*=d; }
257 friend const SimTime operator*(
int d,
const SimTime& x) {
return SimTime(x)*=d; }
258 friend const SimTime operator*(
long d,
const SimTime& x) {
return SimTime(x)*=d; }
259 friend const SimTime operator*(
long long d,
const SimTime& x) {
return SimTime(x)*=d; }
260 friend const SimTime operator*(
unsigned short d,
const SimTime& x) {
return SimTime(x)*=d; }
261 friend const SimTime operator*(
unsigned int d,
const SimTime& x) {
return SimTime(x)*=d; }
262 friend const SimTime operator*(
unsigned long d,
const SimTime& x) {
return SimTime(x)*=d; }
263 friend const SimTime operator*(
unsigned long long d,
const SimTime& x) {
return SimTime(x)*=d; }
264 friend const SimTime operator*(
const cPar& p,
const SimTime& x) {
return SimTime(x)*=p; }
266 friend const SimTime operator/(
const SimTime& x,
double d) {
return SimTime(x)/=d; }
267 friend const SimTime operator/(
const SimTime& x,
short d) {
return SimTime(x)/=d; }
268 friend const SimTime operator/(
const SimTime& x,
int d) {
return SimTime(x)/=d; }
269 friend const SimTime operator/(
const SimTime& x,
long d) {
return SimTime(x)/=d; }
270 friend const SimTime operator/(
const SimTime& x,
long long d) {
return SimTime(x)/=d; }
271 friend const SimTime operator/(
const SimTime& x,
unsigned short d) {
return SimTime(x)/=d; }
272 friend const SimTime operator/(
const SimTime& x,
unsigned int d) {
return SimTime(x)/=d; }
273 friend const SimTime operator/(
const SimTime& x,
unsigned long d) {
return SimTime(x)/=d; }
274 friend const SimTime operator/(
const SimTime& x,
unsigned long long d) {
return SimTime(x)/=d; }
275 friend const SimTime operator/(
const SimTime& x,
const cPar& p) {
return SimTime(x)/=p; }
277 friend double operator/(
const SimTime& x,
const SimTime& y) {
return (
double)x.raw() / (double)y.raw(); }
279 friend double operator/(
double x,
const SimTime& y) {
return x / y.dbl(); }
280 friend double operator/(
short x,
const SimTime& y) {
return (
long long)x / y; }
281 friend double operator/(
int x,
const SimTime& y) {
return (
long long)x / y; }
282 friend double operator/(
long x,
const SimTime& y) {
return (
long long)x / y; }
283 friend SIM_API
double operator/(
long long x,
const SimTime& y);
284 friend double operator/(
unsigned short x,
const SimTime& y) {
return (
unsigned long long)x / y; }
285 friend double operator/(
unsigned int x,
const SimTime& y) {
return (
unsigned long long)x / y; }
286 friend double operator/(
unsigned long x,
const SimTime& y) {
return (
unsigned long long)x / y; }
287 friend SIM_API
double operator/(
unsigned long long x,
const SimTime& y);
288 friend SIM_API
double operator/(
const cPar& p,
const SimTime& x);
307 double dbl()
const {
return t*invfscale;}
357 std::string
str()
const {
char buf[64];
return str(buf);}
366 char *
str(
char *buf)
const {
char *endp;
return SimTime::ttoa(buf, t, getScaleExp(), endp);}
374 std::string ustr()
const;
387 int64_t
raw()
const {
return t;}
429 static void setScaleExp(
int e);
436 static const SimTime parse(
const char *s);
447 static const SimTime parse(
const char *s,
const char *&endp);
458 static char *ttoa(
char *buf, int64_t t,
int scaleexp,
char *&endp);
462 inline std::ostream& operator<<(std::ostream& os,
const SimTime& x)
464 char buf[64];
char *endp;