00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef __SIMTIME_H
00017 #define __SIMTIME_H
00018
00019 #include <string>
00020 #include <iostream>
00021 #include "simkerneldefs.h"
00022 #include "platdep/intxtypes.h"
00023
00024 NAMESPACE_BEGIN
00025
00026 class cPar;
00027
00028
00029 #define INT64_MAX_DBL 9.22337203685e18
00030
00034 enum SimTimeUnit
00035 {
00036 SIMTIME_S = 0,
00037 SIMTIME_MS = -3,
00038 SIMTIME_US = -6,
00039 SIMTIME_NS = -9,
00040 SIMTIME_PS = -12,
00041 SIMTIME_FS = -15
00042 };
00043
00060 class SIM_API SimTime
00061 {
00062 private:
00063 int64 t;
00064
00065 static int scaleexp;
00066 static int64 dscale;
00067 static double fscale;
00068 static double invfscale;
00069
00070 protected:
00071 static void resetScale() {scaleexp = SCALEEXP_UNINITIALIZED;}
00072
00073 private:
00074 template<typename T> void check(T d) {if (scaleexp==SCALEEXP_UNINITIALIZED) initError(d);}
00075 void initError(double d);
00076
00077 bool haveSameSign(int64 a, int64 b) { return (a^b) >= 0; }
00078
00079 int64 toInt64(double i64) {
00080 if (fabs(i64) > INT64_MAX_DBL)
00081 rangeError(i64);
00082 return (int64)i64;
00083 }
00084
00085 void checkedAdd(const SimTime& x) {
00086
00087 bool sameSign = haveSameSign(t, x.t);
00088 t += x.t;
00089 if (sameSign && !haveSameSign(t, x.t))
00090 overflowAdding(x);
00091 }
00092
00093 void checkedSub(const SimTime& x) {
00094
00095 bool differentSign = !haveSameSign(t, x.t);
00096 t -= x.t;
00097 if (differentSign && haveSameSign(t, x.t))
00098 overflowSubtracting(x);
00099 }
00100
00101 void rangeError(double i64);
00102 void overflowAdding(const SimTime& x);
00103 void overflowSubtracting(const SimTime& x);
00104
00105 public:
00106
00107 _OPPDEPRECATED static const int SCALEEXP_S;
00108 _OPPDEPRECATED static const int SCALEEXP_MS;
00109 _OPPDEPRECATED static const int SCALEEXP_US;
00110 _OPPDEPRECATED static const int SCALEEXP_NS;
00111 _OPPDEPRECATED static const int SCALEEXP_PS;
00112 _OPPDEPRECATED static const int SCALEEXP_FS;
00113
00114 static const int SCALEEXP_UNINITIALIZED = 0xffff;
00115
00121 SimTime() {t=0;}
00122
00131 SimTime(double d) {operator=(d);}
00132
00139 SimTime(cPar& d) {operator=(d);}
00140
00141
00142
00143
00159 SimTime(int64 significand, int exponent);
00160
00164 SimTime(const SimTime& x) {operator=(x);}
00166
00169 const SimTime& operator=(double d) {check(d); t=toInt64(fscale*d); return *this;}
00170 const SimTime& operator=(const cPar& d);
00171 const SimTime& operator=(const SimTime& x) {t=x.t; return *this;}
00172 template<typename T> const SimTime& operator=(T d) {check(d); t=toInt64(dscale*d); return *this;}
00173
00174 const SimTime& operator+=(const SimTime& x) {checkedAdd(x); return *this;}
00175 const SimTime& operator-=(const SimTime& x) {checkedSub(x); return *this;}
00176
00177 const SimTime& operator*=(double d) {t=toInt64(t*d); return *this;}
00178 const SimTime& operator/=(double d) {t=toInt64(t/d); return *this;}
00179 const SimTime& operator*=(const cPar& p);
00180 const SimTime& operator/=(const cPar& p);
00181 template<typename T> const SimTime& operator*=(T d) {t*=d; return *this;}
00182 template<typename T> const SimTime& operator/=(T d) {t/=d; return *this;}
00183
00184 bool operator==(const SimTime& x) const {return t==x.t;}
00185 bool operator!=(const SimTime& x) const {return t!=x.t;}
00186 bool operator< (const SimTime& x) const {return t<x.t;}
00187 bool operator> (const SimTime& x) const {return t>x.t;}
00188 bool operator<=(const SimTime& x) const {return t<=x.t;}
00189 bool operator>=(const SimTime& x) const {return t>=x.t;}
00190
00191 SimTime operator-() const {SimTime x; x.t = -t; return x;}
00192
00193 friend const SimTime operator+(const SimTime& x, const SimTime& y);
00194 friend const SimTime operator-(const SimTime& x, const SimTime& y);
00195
00196 friend const SimTime operator*(const SimTime& x, double d);
00197 friend const SimTime operator*(double d, const SimTime& x);
00198 friend const SimTime operator/(const SimTime& x, double d);
00199 friend double operator/(double d, const SimTime& x);
00200 friend double operator/(const SimTime& x, const SimTime& y);
00201
00202 friend const SimTime operator*(const SimTime& x, const cPar& p);
00203 friend const SimTime operator*(const cPar& p, const SimTime& x);
00204 friend const SimTime operator/(const SimTime& x, const cPar& p);
00206
00213 double dbl() const {return t*invfscale;}
00214
00230 int64 inUnit(int exponent) const;
00231
00242 SimTime trunc(int exponent) const {return SimTime(inUnit(exponent), exponent);}
00243
00250 SimTime remainderForUnit(int exponent) const {return (*this) - trunc(exponent);}
00251
00263 void split(int exponent, int64& outValue, SimTime& outRemainder) const;
00264
00268 std::string str() const;
00269
00277 char *str(char *buf) const {char *endp; return SimTime::ttoa(buf, t, getScaleExp(), endp);}
00278
00282 int64 raw() const {return t;}
00283
00287 const SimTime& setRaw(int64 l) {t = l; return *this;}
00288
00293 static const SimTime getMaxTime() {return SimTime().setRaw(INT64_MAX);}
00294
00299 static int64 getScale() {return dscale;}
00300
00305 static int getScaleExp() {return scaleexp;}
00306
00319 static void setScaleExp(int e);
00320
00326 static const SimTime parse(const char *s);
00327
00337 static const SimTime parse(const char *s, const char *&endp);
00338
00348 static char *ttoa(char *buf, int64 t, int scaleexp, char *&endp);
00349 };
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 inline const SimTime operator+(const SimTime& x, const SimTime& y)
00360 {
00361 return SimTime(x)+=y;
00362 }
00363
00364 inline const SimTime operator-(const SimTime& x, const SimTime& y)
00365 {
00366 return SimTime(x)-=y;
00367 }
00368
00369 inline const SimTime operator*(const SimTime& x, double d)
00370 {
00371 return SimTime(x)*=d;
00372 }
00373
00374 inline const SimTime operator*(double d, const SimTime& x)
00375 {
00376 return SimTime(x)*=d;
00377 }
00378
00379 inline const SimTime operator/(const SimTime& x, double d)
00380 {
00381 return SimTime(x)/=d;
00382 }
00383
00384 inline double operator/(double d, const SimTime& x)
00385 {
00386 return d / x.dbl();
00387 }
00388
00389 inline double operator/(const SimTime& x, const SimTime& y)
00390 {
00391 return (double)x.raw() / (double)y.raw();
00392 }
00393
00394 inline std::ostream& operator<<(std::ostream& os, const SimTime& x)
00395 {
00396 char buf[64]; char *endp;
00397 return os << SimTime::ttoa(buf, x.raw(), SimTime::getScaleExp(), endp);
00398 }
00399
00400 NAMESPACE_END
00401
00402
00403 inline int64 _i64mod(const int64& any_t, const int64& positive_u)
00404 {
00405 int64 m = any_t % positive_u;
00406 return m>=0 ? m : m+positive_u;
00407 }
00408
00412 inline const OPP::SimTime floor(const OPP::SimTime& x)
00413 {
00414 int64 u = OPP::SimTime::getScale();
00415 int64 t = x.raw();
00416 return OPP::SimTime().setRaw(t - _i64mod(t,u));
00417 }
00418
00426 inline const OPP::SimTime floor(const OPP::SimTime& x, const OPP::SimTime& unit, const OPP::SimTime& offset = OPP::SimTime())
00427 {
00428 int64 off = offset.raw();
00429 int64 u = unit.raw();
00430 int64 t = x.raw() - off;
00431 return OPP::SimTime().setRaw(t - _i64mod(t,u) + off);
00432 }
00433
00437 inline const OPP::SimTime ceil(const OPP::SimTime& x)
00438 {
00439 int64 u = OPP::SimTime::getScale();
00440 int64 t = x.raw() + u-1;
00441 return OPP::SimTime().setRaw(t - _i64mod(t,u));
00442 }
00443
00448 inline const OPP::SimTime ceil(const OPP::SimTime& x, const OPP::SimTime& unit, const OPP::SimTime& offset = OPP::SimTime())
00449 {
00450 int64 off = offset.raw();
00451 int64 u = unit.raw();
00452 int64 t = x.raw() - off + u-1;
00453 return OPP::SimTime().setRaw(t - _i64mod(t,u) + off);
00454 }
00455
00459 inline const OPP::SimTime fabs(const OPP::SimTime& x)
00460 {
00461 return x.raw()<0 ? OPP::SimTime().setRaw(-x.raw()) : x;
00462 }
00463
00467 inline const OPP::SimTime fmod(const OPP::SimTime& x, const OPP::SimTime& y)
00468 {
00469 return OPP::SimTime().setRaw(x.raw() % y.raw());
00470 }
00471
00472 #endif
00473
00474