LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2005,2006 INRIA | 3 * Copyright (c) 2005,2006 INRIA |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 5 * This program is free software; you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 2 as | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with this program; if not, write to the Free Software | 15 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 17 * |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> | 18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
19 */ | 19 */ |
20 #ifndef TIME_H | 20 #ifndef TIME_H |
21 #define TIME_H | 21 #define TIME_H |
22 | 22 |
23 #include "assert.h" | 23 #include "assert.h" |
24 #include "attribute.h" | 24 #include "attribute.h" |
25 #include "attribute-helper.h" | 25 #include "attribute-helper.h" |
26 #include "int64x64.h" | 26 #include "int64x64.h" |
| 27 #include "unused.h" |
27 #include <stdint.h> | 28 #include <stdint.h> |
| 29 #include <limits> |
28 #include <cmath> | 30 #include <cmath> |
| 31 #include <ostream> |
29 #include <set> | 32 #include <set> |
30 #include <ostream> | |
31 | 33 |
32 namespace ns3 { | 34 namespace ns3 { |
33 | 35 |
34 /** | 36 /** |
35 * \ingroup core | 37 * \ingroup core |
36 * \defgroup time Time | 38 * \defgroup time Time |
37 */ | 39 */ |
38 /** | 40 /** |
39 * \ingroup time | 41 * \ingroup time |
40 * \brief Keep track of time values and allow control of global simulation resol
ution. | 42 * \brief keep track of time values and allow control of global simulation resol
ution |
41 * | 43 * |
42 * This class defines the classic addition/subtraction C++ arithmetic | 44 * This class defines all the classic C++ arithmetic |
43 * operators +, -, +=, -=, and all the classic comparison operators: | 45 * operators +, -, *, /, and all the classic comparison operators: |
44 * ==, !=, <, >, <=, >=. It is thus easy to add, substract, or | 46 * ==, !=, <, >, <=, >=. It is thus easy to add, substract, or |
45 * compare Time objects. | 47 * multiply Time objects. |
46 * | 48 * |
47 * For example: | 49 * For example: |
48 * \code | 50 * \code |
49 * Time t1 = Seconds (10.0); | 51 * Time t1 = Seconds (10.0); |
50 * Time t2 = Seconds (10.0); | 52 * Time t2 = Seconds (10.0); |
51 * Time t3 = t1; | 53 * Time t3 = t1 * t2; |
52 * t3 += t2; | 54 * Time t4 = t1 / t2; |
| 55 * Time t5 = t3 * t1; |
| 56 * Time t6 = t1 / t5; |
| 57 * Time t7 = t3; |
53 * \endcode | 58 * \endcode |
54 * | 59 * |
55 * You can also use the following non-member functions to manipulate | 60 * You can also use the following non-member functions to manipulate |
56 * any of these ns3::Time object: | 61 * any of these ns3::Time object: |
57 * - \ref Abs() | 62 * - \ref ns3-Time-Abs ns3::Abs |
58 * - \ref Max() | 63 * - \ref ns3-Time-Max ns3::Max |
59 * - \ref Min() | 64 * - \ref ns3-Time-Min ns3::Min |
60 * | 65 * |
61 * This class also controls the resolution of the underlying time value. | 66 * This class also controls |
62 * The resolution is the smallest representable time interval. | 67 * the resolution of the underlying time value . The default resolution |
63 * The default resolution is nanoseconds.·· | 68 * is nanoseconds. That is, TimeStep (1).GetNanoSeconds () will return |
64 * | 69 * 1. It is possible to either increase or decrease the resolution and the |
65 * To change the resolution, use SetResolution(). All Time objects created | 70 * code tries really hard to make this easy. |
66 * before the call to SetResolution() will be updated to the new resolution. | 71 * |
67 * This can only be done once! (Tracking each Time object uses 4 pointers. | 72 * If your resolution is X (say, nanoseconds) and if you create Time objects· |
68 * For speed, once we convert the existing instances we discard the recording | 73 * with a lower resolution (say, picoseconds), don't expect that this· |
69 * data structure and stop tracking new instances, so we have no way | 74 * code will return 1: PicoSeconds (1).GetPicoSeconds (). It will most· |
70 * to do a second conversion.) | 75 * likely return 0 because the Time object has only 64 bits of fractional· |
71 * | 76 * precision which means that PicoSeconds (1) is stored as a 64-bit aproximation |
72 * Because of the memory (and modest construction cost) of tracking Time | 77 * of 1/1000 in the Time object. If you later multiply it again by the exact· |
73 * objects, simulations should explicitly choose a resolution before | 78 * value 1000, the result is unlikely to be 1 exactly. It will be close to |
74 * calling Simulator::Run (). | 79 * 1 but not exactly 1. |
75 * | 80 *· |
76 * If you increase the global resolution, you also implicitly decrease | 81 * In general, it is thus a really bad idea to try to use time objects of a |
77 * the range of your simulation. The global simulation time is stored | 82 * resolution higher than the global resolution controlled through· |
78 * in a 64 bit integer, whose interpretation will depend on the global | 83 * Time::SetResolution. If you do need to use picoseconds, it's thus best |
79 * resolution. Therefore the maximum duration of your simulation, | 84 * to switch the global resolution to picoseconds to avoid nasty surprises. |
80 * if you use picoseconds, is 2^64 ps = 2^24 s = 7 months, whereas, | 85 * |
81 * had you used nanoseconds, you could have run for 584 years. | 86 * Another important issue to keep in mind is that if you increase the |
| 87 * global resolution, you also implicitely decrease the range of your simulation
. |
| 88 * i.e., the global simulation time is stored in a 64 bit integer whose interpre
tation |
| 89 * will depend on the global resolution so, 2^64 picoseconds which is the maximu
m |
| 90 * duration of your simulation if the global resolution is picoseconds· |
| 91 * is smaller than 2^64 nanoseconds which is the maximum duration of your simula
tion |
| 92 * if the global resolution is nanoseconds. |
| 93 * |
| 94 * Finally, don't even think about ever changing the global resolution after |
| 95 * creating Time objects: all Time objects created before the call to SetResolut
ion |
| 96 * will contain values which are not updated to the new resolution. In practice, |
| 97 * the default value for the attributes of many models is indeed calculated |
| 98 * before the main function of the main program enters. Because of this, if you |
| 99 * use one of these models (and it's likely), it's going to be hard to change |
| 100 * the global simulation resolution in a way which gives reasonable results. Thi
s |
| 101 * issue has been filed as bug 954 in the ns-3 bugzilla installation. |
82 */ | 102 */ |
83 class Time | 103 class Time |
84 { | 104 { |
85 public: | 105 public: |
86 /** | 106 /** |
87 * The unit to use to interpret a number representing time | 107 * The unit to use to interpret a number representing time |
88 */ | 108 */ |
89 enum Unit | 109 enum Unit |
90 { | 110 { |
91 S = 0, //!< second | 111 S = 0, //!< second |
92 MS = 1, //!< millisecond | 112 MS = 1, //!< millisecond |
93 US = 2, //!< microsecond | 113 US = 2, //!< microsecond |
94 NS = 3, //!< nanosecond | 114 NS = 3, //!< nanosecond |
95 PS = 4, //!< picosecond | 115 PS = 4, //!< picosecond |
96 FS = 5, //!< femtosecond | 116 FS = 5, //!< femtosecond |
97 LAST = 6 | 117 LAST = 6 |
98 }; | 118 }; |
99 | 119 |
100 inline Time &operator = (const Time &o) | 120 inline Time &operator = (const Time &o) |
101 { | 121 { |
102 m_data = o.m_data; | 122 m_data = o.m_data; |
103 return *this; | 123 return *this; |
104 } | 124 } |
105 inline Time &operator = (const int64_t &value) | |
106 { | |
107 m_data = value; | |
108 return *this; | |
109 } | |
110 inline Time () | 125 inline Time () |
111 : m_data () | 126 : m_data () |
112 { | 127 { |
113 TimeSet (this); | 128 if (g_markingTimes) |
| 129 { |
| 130 » Mark (this); |
| 131 } |
114 } | 132 } |
115 inline Time(const Time &o) | 133 inline Time(const Time &o) |
116 : m_data (o.m_data) | 134 : m_data (o.m_data) |
117 { | 135 { |
118 TimeSet (this); | 136 if (g_markingTimes) |
| 137 { |
| 138 » Mark (this); |
| 139 } |
119 } | 140 } |
120 explicit inline Time (double v) | 141 explicit inline Time (double v) |
121 : m_data (lround (v)) | 142 : m_data (lround (v)) |
122 { | 143 { |
123 TimeSet (this); | 144 if (g_markingTimes) |
| 145 { |
| 146 » Mark (this); |
| 147 } |
124 } | 148 } |
125 explicit inline Time (int v) | 149 explicit inline Time (int v) |
126 : m_data (v) | 150 : m_data (v) |
127 { | 151 { |
128 TimeSet (this); | 152 if (g_markingTimes) |
| 153 { |
| 154 » Mark (this); |
| 155 } |
129 } | 156 } |
130 explicit inline Time (long int v) | 157 explicit inline Time (long int v) |
131 : m_data (v) | 158 : m_data (v) |
132 { | 159 { |
133 TimeSet (this); | 160 if (g_markingTimes) |
| 161 { |
| 162 » Mark (this); |
| 163 } |
134 } | 164 } |
135 explicit inline Time (long long int v) | 165 explicit inline Time (long long int v) |
136 : m_data (v) | 166 : m_data (v) |
137 { | 167 { |
138 TimeSet (this); | 168 if (g_markingTimes) |
| 169 { |
| 170 » Mark (this); |
| 171 } |
139 } | 172 } |
140 explicit inline Time (unsigned int v) | 173 explicit inline Time (unsigned int v) |
141 : m_data (v) | 174 : m_data (v) |
142 { | 175 { |
143 TimeSet (this); | 176 if (g_markingTimes) |
| 177 { |
| 178 » Mark (this); |
| 179 } |
144 } | 180 } |
145 explicit inline Time (unsigned long int v) | 181 explicit inline Time (unsigned long int v) |
146 : m_data (v) | 182 : m_data (v) |
147 { | 183 { |
148 TimeSet (this); | 184 if (g_markingTimes) |
| 185 { |
| 186 » Mark (this); |
| 187 } |
149 } | 188 } |
150 explicit inline Time (unsigned long long int v) | 189 explicit inline Time (unsigned long long int v) |
151 : m_data (v) | 190 : m_data (v) |
152 { | 191 { |
153 TimeSet (this); | 192 if (g_markingTimes) |
| 193 { |
| 194 » Mark (this); |
| 195 } |
154 } | 196 } |
155 /** | 197 /** |
156 * \brief Construct Time object from common time expressions like "1ms" | 198 * \brief Construct Time object from common time expressions like "1ms" |
157 * | 199 * |
158 * Supported units include: | 200 * Supported units include: |
159 * - `s` (seconds) | 201 * - `s` (seconds) |
160 * - `ms` (milliseconds) | 202 * - `ms` (milliseconds) |
161 * - `us` (microseconds) | 203 * - `us` (microseconds) |
162 * - `ns` (nanoseconds) | 204 * - `ns` (nanoseconds) |
163 * - `ps` (picoseconds) | 205 * - `ps` (picoseconds) |
164 * - `fs` (femtoseconds) | 206 * - `fs` (femtoseconds) |
165 * | 207 * |
166 * There can be no white space between the numerical portion | 208 * There can be no white space between the numerical portion |
167 * and the units. Any otherwise malformed string causes a fatal error to | 209 * and the units. Any otherwise malformed string causes a fatal error to |
168 * occur. | 210 * occur. |
169 * \param s The string to parse into a Time | 211 * \param s The string to parse into a Time |
170 */ | 212 */ |
171 explicit Time (const std::string & s); | 213 explicit Time (const std::string & s); |
172 | 214 |
173 /** | 215 /** |
| 216 * \brief Minimum representable Time |
| 217 */ |
| 218 static Time Min () |
| 219 { |
| 220 return Time (std::numeric_limits<int64_t>::min ()); |
| 221 } |
| 222 /** |
| 223 * \brief Maximum representable Time |
| 224 */ |
| 225 static Time Max () |
| 226 { |
| 227 return Time (std::numeric_limits<int64_t>::max ()); |
| 228 } |
| 229 ·· |
| 230 /** |
174 * Destructor | 231 * Destructor |
175 */ | 232 */ |
176 ~Time () | 233 ~Time () |
177 { | 234 { |
178 TimeUnset (this); | 235 if (g_markingTimes) |
| 236 { |
| 237 Clear (this); |
| 238 } |
179 } | 239 } |
180 ·· | 240 ·· |
181 /** | 241 /** |
182 * \return true if the time is zero, false otherwise. | 242 * \return true if the time is zero, false otherwise. |
183 */ | 243 */ |
184 inline bool IsZero (void) const | 244 inline bool IsZero (void) const |
185 { | 245 { |
186 return m_data == 0; | 246 return m_data == 0; |
187 } | 247 } |
188 /** | 248 /** |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 } | 455 } |
396 return retval; | 456 return retval; |
397 } | 457 } |
398 inline operator int64x64_t () const | 458 inline operator int64x64_t () const |
399 { | 459 { |
400 return int64x64_t (m_data); | 460 return int64x64_t (m_data); |
401 } | 461 } |
402 explicit inline Time (const int64x64_t &value) | 462 explicit inline Time (const int64x64_t &value) |
403 : m_data (value.GetHigh ()) | 463 : m_data (value.GetHigh ()) |
404 { | 464 { |
405 TimeSet (this); | 465 if (g_markingTimes) |
| 466 { |
| 467 » Mark (this); |
| 468 } |
406 } | 469 } |
407 inline static Time From (const int64x64_t &value) | 470 inline static Time From (const int64x64_t &value) |
408 { | 471 { |
409 return Time (value); | 472 return Time (value); |
410 } | 473 } |
411 | 474 |
412 private: | 475 private: |
413 /** | 476 /** |
414 * How to convert between other units and the current unit | 477 * How to convert between other units and the current unit |
415 */ | 478 */ |
416 struct Information | 479 struct Information |
417 { | 480 { |
418 bool toMul; //!< Multiply when converting To, otherwise
divide | 481 bool toMul; //!< Multiply when converting To, otherwise
divide |
419 bool fromMul; //!< Multiple when converting From, otherwis
e divide | 482 bool fromMul; //!< Multiple when converting From, otherwis
e divide |
420 uint64_t factor; //!< Ratio of this unit / current unit | 483 int64_t factor; //!< Ratio of this unit / current unit»
» |
421 int64x64_t timeTo; //!< Multiplier to convert to this unit | 484 int64x64_t timeTo; //!< Multiplier to convert to this unit»
» |
422 int64x64_t timeFrom; //!< Multiplier to convert from this unit | 485 int64x64_t timeFrom; //!< Multiplier to convert from this unit»
» |
423 }; | 486 }; |
424 /** | 487 /** |
425 * Current time unit, and conversion info. | 488 * Current time unit, and conversion info. |
426 */ | 489 */ |
427 struct Resolution | 490 struct Resolution |
428 { | 491 { |
429 struct Information info[LAST]; //!< Conversion info from current unit | 492 struct Information info[LAST]; //!< Conversion info from current unit |
430 enum Time::Unit unit; //!< Current time unit | 493 enum Time::Unit unit; //!< Current time unit |
431 }; | 494 }; |
432 | 495 |
433 static inline struct Resolution *PeekResolution (void) | 496 static inline struct Resolution *PeekResolution (void) |
434 { | 497 { |
435 static struct Time::Resolution resolution = SetDefaultNsResolution (); | 498 static struct Time::Resolution resolution = SetDefaultNsResolution (); |
436 return &resolution; | 499 return &resolution; |
437 } | 500 } |
438 static inline struct Information *PeekInformation (enum Unit timeUnit) | 501 static inline struct Information *PeekInformation (enum Unit timeUnit) |
439 { | 502 { |
440 return &(PeekResolution ()->info[timeUnit]); | 503 return &(PeekResolution ()->info[timeUnit]); |
441 } | 504 } |
442 | 505 |
443 static struct Resolution SetDefaultNsResolution (void); | 506 static struct Resolution SetDefaultNsResolution (void); |
444 static void SetResolution (enum Unit unit, struct Resolution *resolution, | 507 static void SetResolution (enum Unit unit, struct Resolution *resolution, |
445 const bool convert = true); | 508 const bool convert = true); |
446 | 509 |
447 /** | 510 /** |
448 * Record all instances of Time, so we can rescale them when | 511 * Record all instances of Time, so we can rescale them when |
449 * the resolution changes. | 512 * the resolution changes. |
450 * | 513 * |
451 * \internal | 514 * \intern |
452 * | 515 * |
453 * We use a std::set so we can remove the record easily when | 516 * We use a std::set so we can remove the record easily when |
454 * ~Time() is called. | 517 * ~Time() is called. |
455 * | 518 * |
456 * We don't use Ptr<Time>, because we would have to bloat every Time | 519 * We don't use Ptr<Time>, because we would have to bloat every Time |
457 * instance with SimpleRefCount<Time>. | 520 * instance with SimpleRefCount<Time>. |
458 * | 521 * |
459 * Seems like this should be std::set< Time * const >, but | 522 * Seems like this should be std::set< Time * const >, but |
460 * http://stackoverflow.com/questions/5526019/compile-errors-stdset-with-const
-members | 523 * [Stack Overflow](http://stackoverflow.com/questions/5526019/compile-errors
-stdset-with-const-members) |
461 * (and gcc 4.2) say no. | 524 * says otherwise, quoting the standard: |
462 */ | 525 * |
463 typedef std::set< Time * > TimesSet; | 526 * > §23.1/3 states that std::set key types must be assignable |
464 /** | 527 * > and copy constructable; clearly a const type will not be assignable. |
465 * Get the TimesSet instance. | 528 */ |
466 * | 529 typedef std::set< Time * > MarkedTimes; |
467 * \param [in] deleteMe If true delete the TimesSet, so that it returns a null
pointer ever after | 530 /** |
468 */ | 531 * Record of outstanding Time objects which will need conversion |
469 static TimesSet * GetTimesSet ( const bool deleteMe = false ); | 532 * when the resolution is set. |
470 /** | 533 * |
471 * Helper to clean up at Simulator::Run | 534 * \intern |
472 */ | 535 * |
473 static void DeleteTimesSet (); | 536 * Use a classic static variable so we can check in Time ctors |
474 /** | 537 * without a function call.·· |
475 * Record a Time instance with the TimesSet | 538 * |
476 */ | 539 * We'd really like to initialize this here, but we don't want to require |
477 static void TimeSet (Time * const time); | 540 * C++0x, so we init in time.cc. To ensure that happens before first use, |
478 /** | 541 * we add a call to StaticInit (below) to every compilation unit which |
479 * Remove a Time instance from the TimesSet, called by ~Time() | 542 * includes nstime.h. |
480 */ | 543 */ |
481 static void TimeUnset (Time * const time); | 544 static MarkedTimes * g_markingTimes; |
482 | 545 public: |
483 | 546 /** |
484 /** | 547 * Function to force static initialization of Time |
485 * Convert existing Times to the new unit. | 548 */ |
| 549 static bool StaticInit (); |
| 550 private: |
| 551 |
| 552 /* Friend the Simulator class so it can call the private function |
| 553 ClearMarkedTimes () |
| 554 */ |
| 555 friend class Simulator; |
| 556 /** |
| 557 * Remove all MarkedTimes. |
| 558 * |
| 559 * \intern |
| 560 * Has to be visible to the Simulator class, hence the friending. |
| 561 */ |
| 562 static void ClearMarkedTimes (); |
| 563 /** |
| 564 * Record a Time instance with the MarkedTimes |
| 565 */ |
| 566 static void Mark (Time * const time); |
| 567 /** |
| 568 * Remove a Time instance from the MarkedTimes, called by ~Time() |
| 569 */ |
| 570 static void Clear (Time * const time); |
| 571 /** |
| 572 * Convert existing Times to the new unit. |
486 */ | 573 */ |
487 static void ConvertTimes (const enum Unit unit); | 574 static void ConvertTimes (const enum Unit unit); |
488 | 575 |
489 friend bool operator == (const Time &lhs, const Time &rhs); | 576 friend bool operator == (const Time &lhs, const Time &rhs); |
490 friend bool operator != (const Time &lhs, const Time &rhs); | 577 friend bool operator != (const Time &lhs, const Time &rhs); |
491 friend bool operator <= (const Time &lhs, const Time &rhs); | 578 friend bool operator <= (const Time &lhs, const Time &rhs); |
492 friend bool operator >= (const Time &lhs, const Time &rhs); | 579 friend bool operator >= (const Time &lhs, const Time &rhs); |
493 friend bool operator < (const Time &lhs, const Time &rhs); | 580 friend bool operator < (const Time &lhs, const Time &rhs); |
494 friend bool operator > (const Time &lhs, const Time &rhs); | 581 friend bool operator > (const Time &lhs, const Time &rhs); |
495 friend Time operator + (const Time &lhs, const Time &rhs); | 582 friend Time operator + (const Time &lhs, const Time &rhs); |
496 friend Time operator - (const Time &lhs, const Time &rhs); | 583 friend Time operator - (const Time &lhs, const Time &rhs); |
497 friend Time &operator += (Time &lhs, const Time &rhs); | 584 friend Time &operator += (Time &lhs, const Time &rhs); |
498 friend Time &operator -= (Time &lhs, const Time &rhs); | 585 friend Time &operator -= (Time &lhs, const Time &rhs); |
499 friend Time Abs (const Time &time); | 586 friend Time Abs (const Time &time); |
500 friend Time Max (const Time &ta, const Time &tb); | 587 friend Time Max (const Time &ta, const Time &tb); |
501 friend Time Min (const Time &ta, const Time &tb); | 588 friend Time Min (const Time &ta, const Time &tb); |
502 | 589 |
503 int64_t m_data; | 590 ·· |
504 }; | 591 int64_t m_data; //!< Virtual time value, in the current unit
. |
| 592 ·· |
| 593 }; // class Time |
| 594 ·· |
| 595 |
| 596 // Force static initialization of Time |
| 597 static bool NS_UNUSED_GLOBAL (g_TimeStaticInit) = Time::StaticInit (); |
505 | 598 |
506 inline bool | 599 inline bool |
507 operator == (const Time &lhs, const Time &rhs) | 600 operator == (const Time &lhs, const Time &rhs) |
508 { | 601 { |
509 return lhs.m_data == rhs.m_data; | 602 return lhs.m_data == rhs.m_data; |
510 } | 603 } |
511 inline bool | 604 inline bool |
512 operator != (const Time &lhs, const Time &rhs) | 605 operator != (const Time &lhs, const Time &rhs) |
513 { | 606 { |
514 return lhs.m_data != rhs.m_data; | 607 return lhs.m_data != rhs.m_data; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 lhs.m_data += rhs.m_data; | 639 lhs.m_data += rhs.m_data; |
547 return lhs; | 640 return lhs; |
548 } | 641 } |
549 inline Time &operator -= (Time &lhs, const Time &rhs) | 642 inline Time &operator -= (Time &lhs, const Time &rhs) |
550 { | 643 { |
551 lhs.m_data -= rhs.m_data; | 644 lhs.m_data -= rhs.m_data; |
552 return lhs; | 645 return lhs; |
553 } | 646 } |
554 | 647 |
555 /** | 648 /** |
| 649 * \anchor ns3-Time-Abs |
| 650 * \relates ns3::TimeUnit |
556 * Absolute value function for Time | 651 * Absolute value function for Time |
557 * | |
558 * \param time the input value | 652 * \param time the input value |
559 * \returns the absolute value of the input value. | 653 * \returns the absolute value of the input value. |
560 */ | 654 */ |
561 inline Time Abs (const Time &time) | 655 inline Time Abs (const Time &time) |
562 { | 656 { |
563 return Time ((time.m_data < 0) ? -time.m_data : time.m_data); | 657 return Time ((time.m_data < 0) ? -time.m_data : time.m_data); |
564 } | 658 } |
565 /** | 659 /** |
| 660 * \anchor ns3-Time-Max |
| 661 * \relates ns3::TimeUnit |
566 * \param ta the first value | 662 * \param ta the first value |
567 * \param tb the seconds value | 663 * \param tb the seconds value |
568 * \returns the max of the two input values. | 664 * \returns the max of the two input values. |
569 */ | 665 */ |
570 inline Time Max (const Time &ta, const Time &tb) | 666 inline Time Max (const Time &ta, const Time &tb) |
571 { | 667 { |
572 return Time ((ta.m_data < tb.m_data) ? tb : ta); | 668 return Time ((ta.m_data < tb.m_data) ? tb : ta); |
573 } | 669 } |
574 /** | 670 /** |
575 * \param ta the first value | 671 * \param ta the first value |
576 * \param tb the seconds value | 672 * \param tb the seconds value |
577 * \returns the min of the two input values. | 673 * \returns the min of the two input values. |
578 */ | 674 */ |
579 inline Time Min (const Time &ta, const Time &tb) | 675 inline Time Min (const Time &ta, const Time &tb) |
580 { | 676 { |
581 return Time ((ta.m_data > tb.m_data) ? tb : ta); | 677 return Time ((ta.m_data > tb.m_data) ? tb : ta); |
582 } | 678 } |
583 | 679 |
584 | 680 |
585 /** | 681 /** |
586 * \brief Time output streamer. | 682 * \brief Time output streamer. |
587 *· | 683 *· |
588 * Generates output such as "3.96ns" | 684 * Generates output such as "3.96ns" |
589 * \relates ns3::Time | 685 * \relates ns3::Time |
590 */ | 686 */ |
591 std::ostream& operator<< (std::ostream& os, const Time & time); | 687 std::ostream& operator<< (std::ostream& os, const Time & time); |
592 /** | 688 /** |
593 * \brief Time input streamer | 689 * \brief Time input streamer |
594 * | 690 * |
595 * Uses the Time::Time (std::string) constructor | 691 * Uses the Time::Time (const std::string &) constructor |
596 * \relates ns3::Time | 692 * \relates ns3::Time |
597 */ | 693 */ |
598 std::istream& operator>> (std::istream& is, Time & time); | 694 std::istream& operator>> (std::istream& is, Time & time); |
599 | 695 |
600 /** | 696 /** |
601 * \brief create ns3::Time instances in units of seconds. | 697 * \brief create ns3::Time instances in units of seconds. |
602 * | 698 * |
603 * For example: | 699 * For example: |
604 * \code | 700 * \code |
605 * Time t = Seconds (2.0); | 701 * Time t = Seconds (2.0); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 } | 842 } |
747 | 843 |
748 /** | 844 /** |
749 * \class ns3::TimeValue | 845 * \class ns3::TimeValue |
750 * \brief hold objects of type ns3::Time | 846 * \brief hold objects of type ns3::Time |
751 */ | 847 */ |
752 | 848 |
753 | 849 |
754 ATTRIBUTE_VALUE_DEFINE (Time); | 850 ATTRIBUTE_VALUE_DEFINE (Time); |
755 ATTRIBUTE_ACCESSOR_DEFINE (Time); | 851 ATTRIBUTE_ACCESSOR_DEFINE (Time); |
756 ATTRIBUTE_CHECKER_DEFINE (Time); | 852 |
| 853 /** |
| 854 * \brief Helper to make a Time checker with bounded range. |
| 855 * Both limits are inclusive |
| 856 * |
| 857 * \return the AttributeChecker· |
| 858 */ |
| 859 Ptr<const AttributeChecker> MakeTimeChecker (const Time min, const Time max); |
| 860 |
| 861 /** |
| 862 * \brief Helper to make an unbounded Time checker. |
| 863 * |
| 864 * \return the AttributeChecker |
| 865 */ |
| 866 inline |
| 867 Ptr<const AttributeChecker> MakeTimeChecker (void) |
| 868 { |
| 869 return MakeTimeChecker (Time::Min (), Time::Max ()); |
| 870 } |
| 871 |
| 872 /** |
| 873 * \brief Helper to make a Time checker with a lower bound. |
| 874 * |
| 875 * \return the AttributeChecker |
| 876 */ |
| 877 inline |
| 878 Ptr<const AttributeChecker> MakeTimeChecker (const Time min) |
| 879 { |
| 880 return MakeTimeChecker (min, Time::Max ()); |
| 881 } |
| 882 |
757 | 883 |
758 } // namespace ns3 | 884 } // namespace ns3 |
759 | 885 |
760 #endif /* TIME_H */ | 886 #endif /* TIME_H */ |
LEFT | RIGHT |