00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __adevs_time_h_
00022 #define __adevs_time_h_
00023 #include <cfloat>
00024 #include <iostream>
00025 #include <cmath>
00026 #include <limits>
00027
00029 template <class T> inline T adevs_inf();
00031 template <class T> inline T adevs_zero();
00033 template <class T> inline T adevs_sentinel();
00034
00035 namespace adevs
00036 {
00037
00043 template<class T = double> struct Time
00044 {
00045 T t;
00046 unsigned int c;
00048 static adevs::Time<T> Inf() { return Time<T>(adevs_inf<T>(),0); }
00050 Time(T t = adevs_zero<T>(), unsigned int c = 0):t(t),c(c){}
00052 Time(const Time& t2):t(t2.t),c(t2.c){}
00054 const Time& operator=(const Time& t2)
00055 {
00056 t = t2.t;
00057 c = t2.c;
00058 return *this;
00059 }
00061 bool operator<(T t2) const { return t < t2; }
00066 const Time& operator=(T t2)
00067 {
00068 t = t2;
00069 c = 0;
00070 return *this;
00071 }
00073 Time operator+(const Time& t2) const
00074 {
00075 if (t2.t == 0) return Time(t,t2.c+c);
00076 else return Time(t+t2.t,0);
00077 }
00079 const Time& operator+=(const Time& t2)
00080 {
00081 *this = *this+t2;
00082 return *this;
00083 }
00085 T operator-(T t2) const
00086 {
00087 return t-t2;
00088 }
00090 bool operator==(const Time& t2) const
00091 {
00092 return (t == t2.t && c == t2.c);
00093 }
00095 bool operator!=(const Time& t2) const
00096 {
00097 return !(*this == t2);
00098 }
00100 bool operator<(const Time& t2) const
00101 {
00102 return (t < t2.t || (t == t2.t && c < t2.c));
00103 }
00104 bool operator<=(const Time& t2) const
00105 {
00106 return (*this == t2 || *this < t2);
00107 }
00108 bool operator>(const Time& t2) const
00109 {
00110 return !(*this <= t2);
00111 }
00112 bool operator>=(const Time& t2) const
00113 {
00114 return !(*this < t2);
00115 }
00116 };
00117
00131 inline int fcmp(double x1, double x2, double epsilon)
00132 {
00133 int exponent;
00134 double delta;
00135 double difference;
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 delta = ldexp(epsilon, exponent);
00162
00163 difference = x1 - x2;
00164
00165 if (difference > delta)
00166 return 1;
00167 else if (difference < -delta)
00168 return -1;
00169 else
00170 return 0;
00171 }
00172
00180 class double_fcmp {
00181
00182 private:
00183 double d;
00184
00185 public:
00190 static double epsilon;
00191
00192 double_fcmp(double rhs = 0)
00193 : d(rhs) { }
00194
00195 const double_fcmp& operator=(const double_fcmp& rhs)
00196 {
00197 d = rhs.d;
00198 return *this;
00199 }
00200 const double_fcmp& operator=(double rhs)
00201 {
00202 d = rhs;
00203 return *this;
00204 }
00205 operator double()
00206 {
00207 return d;
00208 }
00209 bool operator<(double rhs) const
00210 {
00211 return (fcmp(d, rhs, epsilon) < 0);
00212 }
00213 bool operator<(const double_fcmp& rhs) const
00214 {
00215 return (fcmp(d, rhs.d, epsilon) < 0);
00216 }
00217 bool operator<=(const double_fcmp& rhs) const
00218 {
00219 return (fcmp(d, rhs.d, epsilon) <= 0);
00220 }
00221 bool operator>(const double_fcmp& rhs) const
00222 {
00223 return (fcmp(d, rhs.d, epsilon) > 0);
00224 }
00225 bool operator>=(const double_fcmp& rhs) const
00226 {
00227 return (fcmp(d, rhs.d, epsilon) >= 0);
00228 }
00229 bool operator==(double rhs) const
00230 {
00231 return (fcmp(d, rhs, epsilon) == 0);
00232 }
00233 bool operator==(const double_fcmp& rhs) const
00234 {
00235 return (fcmp(d, rhs.d, epsilon) == 0);
00236 }
00237 };
00238
00239 }
00240
00241 template <> inline double adevs_inf() {
00242 return std::numeric_limits<double>::max(); }
00243 template <> inline int adevs_inf() {
00244 return std::numeric_limits<int>::max(); }
00245 template <> inline long adevs_inf() {
00246 return std::numeric_limits<long>::max(); }
00247 template <> inline adevs::double_fcmp adevs_inf() {
00248 return std::numeric_limits<double>::max(); }
00249
00250 template <> inline double adevs_zero() { return 0.0; }
00251 template <> inline int adevs_zero() { return 0; }
00252 template <> inline long adevs_zero() { return 0; }
00253 template <> inline adevs::double_fcmp adevs_zero() { return 0.0; }
00254
00255 template <> inline double adevs_sentinel() { return -1.0; }
00256 template <> inline int adevs_sentinel() { return -1; }
00257 template <> inline long adevs_sentinel() { return -1; }
00258 template <> inline adevs::double_fcmp adevs_sentinel() { return -1.0; }
00259
00260 template<class T>
00261 std::ostream& operator<<(std::ostream& strm, const adevs::Time<T>& t);
00262
00263 #endif