adevs
adevs_time.h
1 
31 #ifndef __adevs_time_h_
32 #define __adevs_time_h_
33 #include <cfloat>
34 #include <iostream>
35 #include <cmath>
36 #include <limits>
37 
39 template <class T> inline T adevs_inf();
41 template <class T> inline T adevs_zero();
43 template <class T> inline T adevs_sentinel();
44 
45 namespace adevs
46 {
47 
53 template<class T = double> struct Time
54 {
55  T t;
56  unsigned int c;
58  static adevs::Time<T> Inf() { return Time<T>(adevs_inf<T>(),0); }
60  Time(T t = adevs_zero<T>(), unsigned int c = 0):t(t),c(c){}
62  Time(const Time& t2):t(t2.t),c(t2.c){}
64  const Time& operator=(const Time& t2)
65  {
66  t = t2.t;
67  c = t2.c;
68  return *this;
69  }
71  bool operator<(T t2) const { return t < t2; }
76  const Time& operator=(T t2)
77  {
78  t = t2;
79  c = 0;
80  return *this;
81  }
83  Time operator+(const Time& t2) const
84  {
85  if (t2.t == 0) return Time(t,t2.c+c);
86  else return Time(t+t2.t,0);
87  }
89  const Time& operator+=(const Time& t2)
90  {
91  *this = *this+t2;
92  return *this;
93  }
95  T operator-(T t2) const
96  {
97  return t-t2;
98  }
100  bool operator==(const Time& t2) const
101  {
102  return (t == t2.t && c == t2.c);
103  }
105  bool operator!=(const Time& t2) const
106  {
107  return !(*this == t2);
108  }
110  bool operator<(const Time& t2) const
111  {
112  return (t < t2.t || (t == t2.t && c < t2.c));
113  }
114  bool operator<=(const Time& t2) const
115  {
116  return (*this == t2 || *this < t2);
117  }
118  bool operator>(const Time& t2) const
119  {
120  return !(*this <= t2);
121  }
122  bool operator>=(const Time& t2) const
123  {
124  return !(*this < t2);
125  }
126 };
127 
141 inline int fcmp(double x1, double x2, double epsilon)
142 {
143  int exponent;
144  double delta;
145  double difference;
146 
147  /* Get exponent(max(fabs(x1), fabs(x2))) and store it in exponent. */
148 
149  /* If neither x1 nor x2 is 0, */
150  /* this is equivalent to max(exponent(x1), exponent(x2)). */
151 
152  /* If either x1 or x2 is 0, its exponent returned by frexp would be 0, */
153  /* which is much larger than the exponents of numbers close to 0 in */
154  /* magnitude. But the exponent of 0 should be less than any number */
155  /* whose magnitude is greater than 0. */
156 
157  /* So we only want to set exponent to 0 if both x1 and */
158  /* x2 are 0. Hence, the following works for all x1 and x2. */
159 
160  frexp(fabs(x1) > fabs(x2) ? x1 : x2, &exponent);
161 
162  /* Do the comparison. */
163 
164  /* delta = epsilon * pow(2, exponent) */
165 
166  /* Form a neighborhood around x2 of size delta in either direction. */
167  /* If x1 is within this delta neighborhood of x2, x1 == x2. */
168  /* Otherwise x1 > x2 or x1 < x2, depending on which side of */
169  /* the neighborhood x1 is on. */
170 
171  delta = ldexp(epsilon, exponent);
172 
173  difference = x1 - x2;
174 
175  if (difference > delta)
176  return 1; /* x1 > x2 */
177  else if (difference < -delta)
178  return -1; /* x1 < x2 */
179  else /* -delta <= difference <= delta */
180  return 0; /* x1 == x2 */
181 }
182 
190 class double_fcmp {
191 
192 private:
193  double d;
194 
195 public:
200  static double epsilon;
201 
202  double_fcmp(double rhs = 0)
203  : d(rhs) { }
204 
205  const double_fcmp& operator=(const double_fcmp& rhs)
206  {
207  d = rhs.d;
208  return *this;
209  }
210  const double_fcmp& operator=(double rhs)
211  {
212  d = rhs;
213  return *this;
214  }
215  operator double()
216  {
217  return d;
218  }
219  bool operator<(double rhs) const
220  {
221  return (fcmp(d, rhs, epsilon) < 0);
222  }
223  bool operator<(const double_fcmp& rhs) const
224  {
225  return (fcmp(d, rhs.d, epsilon) < 0);
226  }
227  bool operator<=(const double_fcmp& rhs) const
228  {
229  return (fcmp(d, rhs.d, epsilon) <= 0);
230  }
231  bool operator>(const double_fcmp& rhs) const
232  {
233  return (fcmp(d, rhs.d, epsilon) > 0);
234  }
235  bool operator>=(const double_fcmp& rhs) const
236  {
237  return (fcmp(d, rhs.d, epsilon) >= 0);
238  }
239  bool operator==(double rhs) const
240  {
241  return (fcmp(d, rhs, epsilon) == 0);
242  }
243  bool operator==(const double_fcmp& rhs) const
244  {
245  return (fcmp(d, rhs.d, epsilon) == 0);
246  }
247 };
248 
249 } // end namespace
250 
251 template <> inline double adevs_inf() {
252  return std::numeric_limits<double>::max(); }
253 template <> inline int adevs_inf() {
254  return std::numeric_limits<int>::max(); }
255 template <> inline long adevs_inf() {
256  return std::numeric_limits<long>::max(); }
257 template <> inline adevs::double_fcmp adevs_inf() {
258  return std::numeric_limits<double>::max(); }
259 
260 template <> inline double adevs_zero() { return 0.0; }
261 template <> inline int adevs_zero() { return 0; }
262 template <> inline long adevs_zero() { return 0; }
263 template <> inline adevs::double_fcmp adevs_zero() { return 0.0; }
264 
265 template <> inline double adevs_sentinel() { return -1.0; }
266 template <> inline int adevs_sentinel() { return -1; }
267 template <> inline long adevs_sentinel() { return -1; }
268 template <> inline adevs::double_fcmp adevs_sentinel() { return -1.0; }
269 
270 template<class T>
271 std::ostream& operator<<(std::ostream& strm, const adevs::Time<T>& t);
272 
273 #endif
static adevs::Time< T > Inf()
Value for infinity.
Definition: adevs_time.h:58
const Time & operator=(T t2)
Definition: adevs_time.h:76
Time(const Time &t2)
Copy constructor.
Definition: adevs_time.h:62
const Time & operator=(const Time &t2)
Assignment operator.
Definition: adevs_time.h:64
bool operator==(const Time &t2) const
Equivalence.
Definition: adevs_time.h:100
Definition: adevs_time.h:190
Definition: adevs_time.h:53
Time operator+(const Time &t2) const
Advance operator (this is not commutative or associative!)
Definition: adevs_time.h:83
T operator-(T t2) const
Subtract a real number (used to get the elapsed time)
Definition: adevs_time.h:95
bool operator<(T t2) const
Comparing with a T compares the real field.
Definition: adevs_time.h:71
bool operator<(const Time &t2) const
Order by t then by c.
Definition: adevs_time.h:110
static double epsilon
Definition: adevs_time.h:200
const Time & operator+=(const Time &t2)
Advance and assign.
Definition: adevs_time.h:89
int fcmp(double x1, double x2, double epsilon)
Definition: adevs_time.h:141
bool operator!=(const Time &t2) const
Not equal.
Definition: adevs_time.h:105
Time(T t=adevs_zero< T >(), unsigned int c=0)
Constructor. Default time is (0,0).
Definition: adevs_time.h:60