00001
00031 #ifndef __adevs_time_h_
00032 #define __adevs_time_h_
00033 #include <cfloat>
00034 #include <iostream>
00035 #include <cmath>
00036 #include <limits>
00037
00039 template <class T> inline T adevs_inf();
00041 template <class T> inline T adevs_zero();
00043 template <class T> inline T adevs_sentinel();
00044
00045 namespace adevs
00046 {
00047
00053 template<class T = double> struct Time
00054 {
00055 T t;
00056 unsigned int c;
00058 static adevs::Time<T> Inf() { return Time<T>(adevs_inf<T>(),0); }
00060 Time(T t = adevs_zero<T>(), unsigned int c = 0):t(t),c(c){}
00062 Time(const Time& t2):t(t2.t),c(t2.c){}
00064 const Time& operator=(const Time& t2)
00065 {
00066 t = t2.t;
00067 c = t2.c;
00068 return *this;
00069 }
00071 bool operator<(T t2) const { return t < t2; }
00076 const Time& operator=(T t2)
00077 {
00078 t = t2;
00079 c = 0;
00080 return *this;
00081 }
00083 Time operator+(const Time& t2) const
00084 {
00085 if (t2.t == 0) return Time(t,t2.c+c);
00086 else return Time(t+t2.t,0);
00087 }
00089 const Time& operator+=(const Time& t2)
00090 {
00091 *this = *this+t2;
00092 return *this;
00093 }
00095 T operator-(T t2) const
00096 {
00097 return t-t2;
00098 }
00100 bool operator==(const Time& t2) const
00101 {
00102 return (t == t2.t && c == t2.c);
00103 }
00105 bool operator!=(const Time& t2) const
00106 {
00107 return !(*this == t2);
00108 }
00110 bool operator<(const Time& t2) const
00111 {
00112 return (t < t2.t || (t == t2.t && c < t2.c));
00113 }
00114 bool operator<=(const Time& t2) const
00115 {
00116 return (*this == t2 || *this < t2);
00117 }
00118 bool operator>(const Time& t2) const
00119 {
00120 return !(*this <= t2);
00121 }
00122 bool operator>=(const Time& t2) const
00123 {
00124 return !(*this < t2);
00125 }
00126 };
00127
00141 inline int fcmp(double x1, double x2, double epsilon)
00142 {
00143 int exponent;
00144 double delta;
00145 double difference;
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 delta = ldexp(epsilon, exponent);
00172
00173 difference = x1 - x2;
00174
00175 if (difference > delta)
00176 return 1;
00177 else if (difference < -delta)
00178 return -1;
00179 else
00180 return 0;
00181 }
00182
00190 class double_fcmp {
00191
00192 private:
00193 double d;
00194
00195 public:
00200 static double epsilon;
00201
00202 double_fcmp(double rhs = 0)
00203 : d(rhs) { }
00204
00205 const double_fcmp& operator=(const double_fcmp& rhs)
00206 {
00207 d = rhs.d;
00208 return *this;
00209 }
00210 const double_fcmp& operator=(double rhs)
00211 {
00212 d = rhs;
00213 return *this;
00214 }
00215 operator double()
00216 {
00217 return d;
00218 }
00219 bool operator<(double rhs) const
00220 {
00221 return (fcmp(d, rhs, epsilon) < 0);
00222 }
00223 bool operator<(const double_fcmp& rhs) const
00224 {
00225 return (fcmp(d, rhs.d, epsilon) < 0);
00226 }
00227 bool operator<=(const double_fcmp& rhs) const
00228 {
00229 return (fcmp(d, rhs.d, epsilon) <= 0);
00230 }
00231 bool operator>(const double_fcmp& rhs) const
00232 {
00233 return (fcmp(d, rhs.d, epsilon) > 0);
00234 }
00235 bool operator>=(const double_fcmp& rhs) const
00236 {
00237 return (fcmp(d, rhs.d, epsilon) >= 0);
00238 }
00239 bool operator==(double rhs) const
00240 {
00241 return (fcmp(d, rhs, epsilon) == 0);
00242 }
00243 bool operator==(const double_fcmp& rhs) const
00244 {
00245 return (fcmp(d, rhs.d, epsilon) == 0);
00246 }
00247 };
00248
00249 }
00250
00251 template <> inline long double adevs_inf() {
00252 return std::numeric_limits<long double>::max(); }
00253 template <> inline double adevs_inf() {
00254 return std::numeric_limits<double>::max(); }
00255 template <> inline int adevs_inf() {
00256 return std::numeric_limits<int>::max(); }
00257 template <> inline long adevs_inf() {
00258 return std::numeric_limits<long>::max(); }
00259 template <> inline adevs::double_fcmp adevs_inf() {
00260 return std::numeric_limits<double>::max(); }
00261
00262 template <> inline long double adevs_zero() { return 0.0L; }
00263 template <> inline double adevs_zero() { return 0.0; }
00264 template <> inline int adevs_zero() { return 0; }
00265 template <> inline long adevs_zero() { return 0; }
00266 template <> inline adevs::double_fcmp adevs_zero() { return 0.0; }
00267
00268 template <> inline long double adevs_sentinel() { return -1.0L; }
00269 template <> inline double adevs_sentinel() { return -1.0; }
00270 template <> inline int adevs_sentinel() { return -1; }
00271 template <> inline long adevs_sentinel() { return -1; }
00272 template <> inline adevs::double_fcmp adevs_sentinel() { return -1.0; }
00273
00274 template<class T>
00275 std::ostream& operator<<(std::ostream& strm, const adevs::Time<T>& t);
00276
00277 #endif