1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
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
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
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
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #ifndef TIME_H
21 #define TIME_H
22 
23 #include "assert.h"
24 #include "attribute.h"
25 #include "attribute-helper.h"
26 #include "event-id.h"
27 #include "int64x64.h"
28 #include "unused.h"
29 #include <stdint.h>
30 #include <limits>
31 #include <cmath>
32 #include <ostream>
33 #include <set>
34 
35 /**
36  * \file
37  * \ingroup time
38  * Declaration of classes ns3::Time and ns3::TimeWithUnit,
39  * and the TimeValue implementation classes.
40  */
41 
42 namespace ns3 {
43 
44 class TimeWithUnit;
45 
46 /**
47  * \ingroup core
48  * \defgroup time Virtual Time
49  *  Management of virtual time in real world units.
50  *
51  * The underlying simulator is unit agnostic, just dealing with
52  * dimensionless virtual time.  Models usually need to handle
53  * time in real world units, such as seconds, and conversions/scaling
54  * between different units, between minutes and seconds, for example.
55  *
56  * The convenience constructors in the \ref timecivil "Standard Units" module
57  * make it easy to create Times in specific units.
58  *
59  * The Time::SetResolution() function allows a one-time change of the
60  * base resolution, before Simulator::Run().
61  */
62 /**
63  * \ingroup time
64  * Simulation virtual time values and global simulation resolution.
65  *
66  * This class defines all the classic C++ addition/subtraction
67  * operators: +, -, +=, -=; and all the classic comparison operators:
68  * ==, !=, <, >, <=, >=. It is thus easy to add, subtract, or
69  * compare Time objects.
70  *
71  * For example:
72  * \code
73  * Time t1 = Seconds (10.0);
74  * Time t2 = Seconds (10.0);
75  * Time t3 = t1;
76  * t3 += t2;
77  * \endcode
78  *
79  * You can also use the following non-member functions to manipulate
80  * any of these ns3::Time object:
81  *  - Abs(Time)
82  *  - Max(Time,Time)
83  *  - Min(Time,Time)
84  *
85  * This class also controls the resolution of the underlying time representation.
86  * The resolution is the smallest representable time interval.
87  * The default resolution is nanoseconds.
88  *
89  * To change the resolution, use SetResolution().  All Time objects created
90  * before the call to SetResolution() will be updated to the new resolution.
91  * This can only be done once!  (Tracking each Time object uses 4 pointers.
92  * For speed, once we convert the existing instances we discard the recording
93  * data structure and stop tracking new instances, so we have no way
94  * to do a second conversion.)
95  *
96  * If you increase the global resolution, you also implicitly decrease
97  * the maximum simulation duration.  The global simulation time is stored
98  * in a 64 bit integer whose interpretation will depend on the global
99  * resolution.  Therefore the maximum possible duration of your simulation
100  * if you use picoseconds is 2^64 ps = 2^24 s = 7 months, whereas,
101  * had you used nanoseconds, you could have run for 584 years.
102  */
103 class Time
104 {
105 public:
106   /**
107    * The unit to use to interpret a number representing time
108    */
109   enum Unit
110   {
111     Y   = 0,   //!< year, 365 days
112     D   = 1,   //!< day, 24 hours
113     H   = 2,   //!< hour, 60 minutes
114     MIN = 3,   //!< minute, 60 seconds
115     S   = 4,   //!< second
116     MS  = 5,   //!< millisecond
117     US  = 6,   //!< microsecond
118     NS  = 7,   //!< nanosecond
119     PS  = 8,   //!< picosecond
120     FS  = 9,   //!< femtosecond
121     LAST = 10, //!< marker for last normal value
122     AUTO = 11  //!< auto-scale output when using Time::As()
123   };
124 
125   /**
126    *  Assignment operator
127    * \param [in] o Time to assign.
128    * \return The Time.
129    */
130   inline Time & operator = (const Time & o)
131   {
132     m_data = o.m_data;
133     return *this;
134   }
135   /** Default constructor, with value 0. */
Time()136   inline Time ()
137     : m_data ()
138   {
139     if (g_markingTimes)
140       {
141         Mark (this);
142       }
143   }
144   /**
145    *  Copy constructor
146    *
147    * \param [in] o Time to copy
148    */
Time(const Time & o)149   inline Time (const Time & o)
150     : m_data (o.m_data)
151   {
152     if (g_markingTimes)
153       {
154         Mark (this);
155       }
156   }
157 
158   /**
159    * Move constructor
160    *
161    * \param [in] o Time from which take the data
162    */
Time(Time && o)163   Time (Time &&o)
164     : m_data (o.m_data)
165   {
166     if (g_markingTimes)
167       {
168         Mark (this);
169       }
170   }
171   /**
172    * \name Numeric constructors
173    *  Construct from a numeric value.
174    * @{
175    */
176   /**
177    *  Construct from a numeric value.
178    *  The current time resolution will be assumed as the unit.
179    *  \param [in] v The value.
180    */
Time(double v)181   explicit inline Time (double v)
182     : m_data (lround (v))
183   {
184     if (g_markingTimes)
185       {
186         Mark (this);
187       }
188   }
Time(int v)189   explicit inline Time (int v)
190     : m_data (v)
191   {
192     if (g_markingTimes)
193       {
194         Mark (this);
195       }
196   }
Time(long int v)197   explicit inline Time (long int v)
198     : m_data (v)
199   {
200     if (g_markingTimes)
201       {
202         Mark (this);
203       }
204   }
Time(long long int v)205   explicit inline Time (long long int v)
206     : m_data (v)
207   {
208     if (g_markingTimes)
209       {
210         Mark (this);
211       }
212   }
Time(unsigned int v)213   explicit inline Time (unsigned int v)
214     : m_data (v)
215   {
216     if (g_markingTimes)
217       {
218         Mark (this);
219       }
220   }
Time(unsigned long int v)221   explicit inline Time (unsigned long int v)
222     : m_data (v)
223   {
224     if (g_markingTimes)
225       {
226         Mark (this);
227       }
228   }
Time(unsigned long long int v)229   explicit inline Time (unsigned long long int v)
230     : m_data (v)
231   {
232     if (g_markingTimes)
233       {
234         Mark (this);
235       }
236   }
Time(const int64x64_t & v)237   explicit inline Time (const int64x64_t & v)
238     : m_data (v.Round ())
239   {
240     if (g_markingTimes)
241       {
242         Mark (this);
243       }
244   }
245   /**@}*/  // Numeric constructors
246 
247   /**
248    * Construct Time object from common time expressions like "1ms"
249    *
250    * Supported units include:
251    * - `s`  (seconds)
252    * - `ms` (milliseconds)
253    * - `us` (microseconds)
254    * - `ns` (nanoseconds)
255    * - `ps` (picoseconds)
256    * - `fs` (femtoseconds)
257    * - `min`  (minutes)
258    * - `h`  (hours)
259    * - `d`  (days)
260    * - `y`  (years)
261    *
262    * There can be no white space between the numerical portion
263    * and the units.  Any otherwise malformed string causes a fatal error to
264    * occur.
265    * \param [in] s The string to parse into a Time
266    */
267   explicit Time (const std::string & s);
268 
269   /**
270    * Minimum representable Time
271    * Not to be confused with Min(Time,Time).
272    * \returns the minimum representable Time.
273    */
Min()274   static Time Min ()
275   {
276     return Time (std::numeric_limits<int64_t>::min ());
277   }
278   /**
279    * Maximum representable Time
280    * Not to be confused with Max(Time,Time).
281    * \returns the maximum representable Time.
282    */
Max()283   static Time Max ()
284   {
285     return Time (std::numeric_limits<int64_t>::max ());
286   }
287 
288   /** Destructor */
~Time()289   ~Time ()
290   {
291     if (g_markingTimes)
292       {
293         Clear (this);
294       }
295   }
296 
297   /**
298    * Exactly equivalent to `t == 0`.
299    * \return \c true if the time is zero, \c false otherwise.
300   */
IsZero(void)301   inline bool IsZero (void) const
302   {
303     return m_data == 0;
304   }
305   /**
306    * Exactly equivalent to `t <= 0`.
307    * \return \c true if the time is negative or zero, \c false otherwise.
308    */
IsNegative(void)309   inline bool IsNegative (void) const
310   {
311     return m_data <= 0;
312   }
313   /**
314    * Exactly equivalent to `t >= 0`.
315    * \return \c true if the time is positive or zero, \c false otherwise.
316    */
IsPositive(void)317   inline bool IsPositive (void) const
318   {
319     return m_data >= 0;
320   }
321   /**
322    * Exactly equivalent to `t < 0`.
323    * \return \c true if the time is strictly negative, \c false otherwise.
324    */
IsStrictlyNegative(void)325   inline bool IsStrictlyNegative (void) const
326   {
327     return m_data < 0;
328   }
329   /**
330    * Exactly equivalent to `t > 0`.
331    * \return \c true if the time is strictly positive, \c false otherwise.
332    */
IsStrictlyPositive(void)333   inline bool IsStrictlyPositive (void) const
334   {
335     return m_data > 0;
336   }
337   /**
338    *  Compare \pname{this} to another Time
339    *
340    * \param [in] o The other Time
341    * \return -1,0,+1 if `this < o`, `this == o`, or `this > o`
342    */
Compare(const Time & o)343   inline int Compare (const Time & o) const
344   {
345     return (m_data < o.m_data) ? -1 : (m_data == o.m_data) ? 0 : 1;
346   }
347 
348   /**
349    * \name Convert to Number in a Unit
350    * Convert a Time to number, in indicated units.
351    *
352    * Conversions to seconds and larger will return doubles, with
353    * possible loss of precision.  Conversions to units smaller than
354    * seconds will be rounded.
355    *
356    * @{
357    */
358   /**
359    * Get an approximation of the time stored in this instance
360    * in the indicated unit.
361    *
362    * \return An approximate value in the indicated unit.
363    */
GetYears(void)364   inline double GetYears (void) const
365   {
366     return ToDouble (Time::Y);
367   }
GetDays(void)368   inline double GetDays (void) const
369   {
370     return ToDouble (Time::D);
371   }
GetHours(void)372   inline double GetHours (void) const
373   {
374     return ToDouble (Time::H);
375   }
GetMinutes(void)376   inline double GetMinutes (void) const
377   {
378     return ToDouble (Time::MIN);
379   }
GetSeconds(void)380   inline double GetSeconds (void) const
381   {
382     return ToDouble (Time::S);
383   }
GetMilliSeconds(void)384   inline int64_t GetMilliSeconds (void) const
385   {
386     return ToInteger (Time::MS);
387   }
GetMicroSeconds(void)388   inline int64_t GetMicroSeconds (void) const
389   {
390     return ToInteger (Time::US);
391   }
GetNanoSeconds(void)392   inline int64_t GetNanoSeconds (void) const
393   {
394     return ToInteger (Time::NS);
395   }
GetPicoSeconds(void)396   inline int64_t GetPicoSeconds (void) const
397   {
398     return ToInteger (Time::PS);
399   }
GetFemtoSeconds(void)400   inline int64_t GetFemtoSeconds (void) const
401   {
402     return ToInteger (Time::FS);
403   }
404   /**@}*/  // Convert to Number in a Unit.
405 
406   /**
407    * \name Convert to Raw Value
408    * Convert a Time to a number in the current resolution units.
409    *
410    * @{
411    */
412   /**
413    * Get the raw time value, in the current resolution unit.
414    * \returns The raw time value
415    */
GetTimeStep(void)416   inline int64_t GetTimeStep (void) const
417   {
418     return m_data;
419   }
GetDouble(void)420   inline double GetDouble (void) const
421   {
422     return static_cast<double> (m_data);
423   }
GetInteger(void)424   inline int64_t GetInteger (void) const
425   {
426     return GetTimeStep ();
427   }
428   /**@}*/  // Convert to Raw Value
429 
430 
431   /**
432    * \param [in] resolution The new resolution to use
433    *
434    * Change the global resolution used to convert all
435    * user-provided time values in Time objects and Time objects
436    * in user-expected time units.
437    */
438   static void SetResolution (enum Unit resolution);
439   /**
440    * \returns The current global resolution.
441    */
442   static enum Unit GetResolution (void);
443 
444 
445   /**
446    *  Create a Time in the current unit.
447    *
448    *  \param [in] value The value of the new Time.
449    *  \return A Time with \pname{value} in the current time unit.
450    */
From(const int64x64_t & value)451   inline static Time From (const int64x64_t & value)
452   {
453     return Time (value);
454   }
455   /**
456    * \name Create Times from Values and Units
457    * Create Times from values given in the indicated units.
458    *
459    * @{
460    */
461   /**
462    *  Create a Time equal to \pname{value}  in unit \c unit
463    *
464    *  \param [in] value The new Time value, expressed in \c unit
465    *  \param [in] unit The unit of \pname{value}
466    *  \return The Time representing \pname{value} in \c unit
467    */
FromInteger(uint64_t value,enum Unit unit)468   inline static Time FromInteger (uint64_t value, enum Unit unit)
469   {
470     struct Information *info = PeekInformation (unit);
471     if (info->fromMul)
472       {
473         value *= info->factor;
474       }
475     else
476       {
477         value /= info->factor;
478       }
479     return Time (value);
480   }
FromDouble(double value,enum Unit unit)481   inline static Time FromDouble (double value, enum Unit unit)
482   {
483     return From (int64x64_t (value), unit);
484   }
From(const int64x64_t & value,enum Unit unit)485   inline static Time From (const int64x64_t & value, enum Unit unit)
486   {
487     struct Information *info = PeekInformation (unit);
488     // DO NOT REMOVE this temporary variable. It's here
489     // to work around a compiler bug in gcc 3.4
490     int64x64_t retval = value;
491     if (info->fromMul)
492       {
493         retval *= info->timeFrom;
494       }
495     else
496       {
497         retval.MulByInvert (info->timeFrom);
498       }
499     return Time (retval);
500   }
501   /**@}*/  // Create Times from Values and Units
502 
503 
504   /**
505    * \name Get Times as Numbers in Specified Units
506    * Get the Time as integers or doubles in the indicated unit.
507    *
508    * @{
509    */
510   /**
511    *  Get the Time value expressed in a particular unit.
512    *
513    *  \param [in] unit The desired unit
514    *  \return The Time expressed in \pname{unit}
515    */
ToInteger(enum Unit unit)516   inline int64_t ToInteger (enum Unit unit) const
517   {
518     struct Information *info = PeekInformation (unit);
519     int64_t v = m_data;
520     if (info->toMul)
521       {
522         v *= info->factor;
523       }
524     else
525       {
526         v /= info->factor;
527       }
528     return v;
529   }
ToDouble(enum Unit unit)530   inline double ToDouble (enum Unit unit) const
531   {
532     return To (unit).GetDouble ();
533   }
To(enum Unit unit)534   inline int64x64_t To (enum Unit unit) const
535   {
536     struct Information *info = PeekInformation (unit);
537     int64x64_t retval = int64x64_t (m_data);
538     if (info->toMul)
539       {
540         retval *= info->timeTo;
541       }
542     else
543       {
544         retval.MulByInvert (info->timeTo);
545       }
546     return retval;
547   }
548   /**@}*/  // Get Times as Numbers in Specified Units
549 
550   /**
551    * Round a Time to a specific unit.
552    * Rounding is to nearest integer.
553    * \return The Time rounded to the specific unit.
554    */
RoundTo(enum Unit unit)555   Time RoundTo (enum Unit unit) const
556   {
557     return From (this->To (unit).Round (), unit);
558   }
559 
560   /**
561    * Attach a unit to a Time, to facilitate output in a specific unit.
562    *
563    * For example,
564    * \code
565    *   Time t (3.14e9);  // Pi seconds
566    *   std::cout << t.As (Time::MS) << std::endl;
567    * \endcode
568    * will print ``+3140.0ms``
569    *
570    * \param [in] unit The unit to use.
571    * \return The Time with embedded unit.
572    */
573   TimeWithUnit As (const enum Unit unit = Time::AUTO) const;
574 
575   /**
576    * TracedCallback signature for Time
577    *
578    * \param [in] value Current value of Time
579    */
580   typedef void (* TracedCallback)(Time value);
581 
582 private:
583   /** How to convert between other units and the current unit. */
584   struct Information
585   {
586     bool toMul;                     //!< Multiply when converting To, otherwise divide
587     bool fromMul;                   //!< Multiple when converting From, otherwise divide
588     int64_t factor;                 //!< Ratio of this unit / current unit
589     int64x64_t timeTo;              //!< Multiplier to convert to this unit
590     int64x64_t timeFrom;            //!< Multiplier to convert from this unit
591   };
592   /** Current time unit, and conversion info. */
593   struct Resolution
594   {
595     struct Information info[LAST];  //!<  Conversion info from current unit
596     enum Time::Unit unit;           //!<  Current time unit
597   };
598 
599   /**
600    *  Get the current Resolution
601    *
602    * \return A pointer to the current Resolution
603    */
PeekResolution(void)604   static inline struct Resolution * PeekResolution (void)
605   {
606     static struct Time::Resolution resolution = SetDefaultNsResolution ();
607     return &resolution;
608   }
609   /**
610    *  Get the Information record for \pname{timeUnit} for the current Resolution
611    *
612    *  \param [in] timeUnit The Unit to get Information for
613    *  \return The Information for \pname{timeUnit}
614    */
PeekInformation(enum Unit timeUnit)615   static inline struct Information * PeekInformation (enum Unit timeUnit)
616   {
617     return &(PeekResolution ()->info[timeUnit]);
618   }
619 
620   /**
621    *  Set the default resolution
622    *
623    * \return The Resolution object for the default resolution.
624    */
625   static struct Resolution SetDefaultNsResolution (void);
626   /**
627    *  Set the current Resolution.
628    *
629    *  \param [in] unit The unit to use as the new resolution.
630    *  \param [in,out] resolution The Resolution record to update.
631    *  \param [in] convert Whether to convert existing Time objects to the new resolution.
632    */
633   static void SetResolution (enum Unit unit, struct Resolution *resolution,
634                              const bool convert = true);
635 
636   /**
637    *  Record all instances of Time, so we can rescale them when
638    *  the resolution changes.
639    *
640    *  \internal
641    *
642    *  We use a std::set so we can remove the record easily when
643    *  ~Time() is called.
644    *
645    *  We don't use Ptr<Time>, because we would have to bloat every Time
646    *  instance with SimpleRefCount<Time>.
647    *
648    *  Seems like this should be std::set< Time * const >, but
649    *  [Stack Overflow](http://stackoverflow.com/questions/5526019/compile-errors-stdset-with-const-members)
650    *  says otherwise, quoting the standard:
651    *
652    *  > & sect;23.1/3 states that std::set key types must be assignable
653    *  > and copy constructable; clearly a const type will not be assignable.
654    */
655   typedef std::set< Time * > MarkedTimes;
656   /**
657    *  Record of outstanding Time objects which will need conversion
658    *  when the resolution is set.
659    *
660    *  \internal
661    *
662    *  Use a classic static variable so we can check in Time ctors
663    *  without a function call.
664    *
665    *  We'd really like to initialize this here, but we don't want to require
666    *  C++0x, so we init in time.cc.  To ensure that happens before first use,
667    *  we add a call to StaticInit (below) to every compilation unit which
668    *  includes nstime.h.
669    */
670   static MarkedTimes * g_markingTimes;
671 
672 public:
673   /**
674    *  Function to force static initialization of Time.
675    *
676    * \return \c true on the first call
677    */
678   static bool StaticInit ();
679 private:
680   /**
681    * \cond HIDE_FROM_DOXYGEN
682    * Doxygen bug throws a warning here, so hide from Doxygen.
683    *
684    * Friend the Simulator class so it can call the private function
685    * ClearMarkedTimes ()
686    */
687   friend class Simulator;
688   /** \endcond */
689 
690   /**
691    *  Remove all MarkedTimes.
692    *
693    *  \internal
694    *  Has to be visible to the Simulator class, hence the friending.
695    */
696   static void ClearMarkedTimes ();
697   /**
698    *  Record a Time instance with the MarkedTimes.
699    *  \param [in] time The Time instance to record.
700    */
701   static void Mark (Time * const time);
702   /**
703    *  Remove a Time instance from the MarkedTimes, called by ~Time().
704    *  \param [in] time The Time instance to remove.
705    */
706   static void Clear (Time * const time);
707   /**
708    *  Convert existing Times to the new unit.
709    *  \param [in] unit The Unit to convert existing Times to.
710    */
711   static void ConvertTimes (const enum Unit unit);
712 
713 
714   // Operator and related functions which need access
715 
716   /**
717    * \name Comparison operators
718    * @{
719    */
720   friend bool operator == (const Time & lhs, const Time & rhs);
721   friend bool operator != (const Time & lhs, const Time & rhs);
722   friend bool operator <= (const Time & lhs, const Time & rhs);
723   friend bool operator >= (const Time & lhs, const Time & rhs);
724   friend bool operator <  (const Time & lhs, const Time & rhs);
725   friend bool operator >  (const Time & lhs, const Time & rhs);
726   friend bool operator <  (const Time & time,   const EventId & event);
727   /**@}*/
728   /**
729    * \name Arithmetic operators
730    * @{
731    */
732   friend Time operator +  (const Time & lhs, const Time & rhs);
733   friend Time operator -  (const Time & lhs, const Time & rhs);
734   friend Time operator *  (const Time & lhs, const int64x64_t & rhs);
735   friend Time operator *  (const int64x64_t & lhs, const Time & rhs);
736 
737   template<class T>
738   friend typename std::enable_if<std::is_integral<T>::value, Time>::type
739   operator * (const Time& lhs, T rhs);
740 
741   //this function uses is_arithmetic because it can be used by both
742   //integers and decimal types
743   /**
744    * Limited to \c is_arithmetic matches for the T argument to reduce the chances
745    * of matching some arbitrary object type.
746    */
747   template<class T>
748   friend typename std::enable_if<std::is_arithmetic<T>::value, Time>::type
749   operator * (T lhs, const Time& rhs);
750 
751   template<class T>
752   friend typename std::enable_if<std::is_floating_point<T>::value, Time>::type
753   operator * (const Time& lhs, T rhs);
754 
755   friend int64x64_t operator / (const Time & lhs, const Time & rhs);
756   friend Time operator /  (const Time & lhs, const int64x64_t & rhs);
757 
758   template<class T>
759   friend typename std::enable_if<std::is_integral<T>::value, Time>::type
760   operator / (const Time& lhs, T rhs);
761 
762   template<class T>
763   friend typename std::enable_if<std::is_floating_point<T>::value, Time>::type
764   operator / (const Time& lhs, T rhs);
765 
766   friend Time operator %  (const Time & lhs, const Time & rhs);
767   friend int64_t Div      (const Time & lhs, const Time & rhs);
768   friend Time Rem         (const Time & lhs, const Time & rhs);
769 
770   /**@}*/
771   /**
772    * \name Compound assignment operators
773    * @{
774    */
775   friend Time & operator += (Time & lhs, const Time & rhs);
776   friend Time & operator -= (Time & lhs, const Time & rhs);
777   /**@}*/
778 
779   /**
780    * Absolute value function for Time
781    * \param [in] time The input value
782    * \returns The absolute value of the input value
783    */
784   friend Time Abs (const Time & time);
785   /**
786    *  Max function for Time.
787    *  \param [in] timeA The first value
788    *  \param [in] timeB The seconds value
789    *  \returns The max of the two input values.
790    */
791   friend Time Max (const Time & timeA, const Time & timeB);
792   /**
793    *  Min function for Time.
794    *  \param [in] timeA The first value
795    *  \param [in] timeB The seconds value
796    *  \returns The min of the two input values.
797    */
798   friend Time Min (const Time & timeA, const Time & timeB);
799 
800 
801   int64_t m_data;  //!< Virtual time value, in the current unit.
802 
803 };  // class Time
804 
805 namespace TracedValueCallback {
806 
807 /**
808  * TracedValue callback signature for Time
809  *
810  * \param [in] oldValue Original value of the traced variable
811  * \param [in] newValue New value of the traced variable
812  */
813 typedef void (* Time)(Time oldValue, Time newValue);
814 
815 }  // namespace TracedValueCallback
816 
817 /**
818  * Force static initialization order of Time in each compilation unit.
819  * This is internal to the Time implementation.
820  * \relates Time
821  */
822 static bool NS_UNUSED_GLOBAL (g_TimeStaticInit) = Time::StaticInit ();
823 
824 /**
825  * Equality operator for Time.
826  * \param [in] lhs The first value
827  * \param [in] rhs The second value
828  * \returns \c true if the two input values are equal.
829  */
830 inline bool
831 operator == (const Time & lhs, const Time & rhs)
832 {
833   return lhs.m_data == rhs.m_data;
834 }
835 /**
836  * Inequality operator for Time.
837  * \param [in] lhs The first value
838  * \param [in] rhs The second value
839  * \returns \c true if the two input values not are equal.
840  */
841 inline bool
842 operator != (const Time & lhs, const Time & rhs)
843 {
844   return lhs.m_data != rhs.m_data;
845 }
846 /**
847  * Less than or equal operator for Time.
848  * \param [in] lhs The first value
849  * \param [in] rhs The second value
850  * \returns \c true if the first input value is less than or equal to the second input value.
851  */
852 inline bool
853 operator <= (const Time & lhs, const Time & rhs)
854 {
855   return lhs.m_data <= rhs.m_data;
856 }
857 /**
858  * Greater than or equal operator for Time.
859  * \param [in] lhs The first value
860  * \param [in] rhs The second value
861  * \returns \c true if the first input value is greater than or equal to the second input value.
862  */
863 inline bool
864 operator >= (const Time & lhs, const Time & rhs)
865 {
866   return lhs.m_data >= rhs.m_data;
867 }
868 /**
869  * Less than operator for Time.
870  * \param [in] lhs The first value
871  * \param [in] rhs The second value
872  * \returns \c true if the first input value is less than the second input value.
873  */
874 inline bool
875 operator < (const Time & lhs, const Time & rhs)
876 {
877   return lhs.m_data < rhs.m_data;
878 }
879 /**
880  * Greater than operator for Time.
881  * \param [in] lhs The first value
882  * \param [in] rhs The second value
883  * \returns \c true if the first input value is greater than the second input value.
884  */
885 inline bool
886 operator > (const Time & lhs, const Time & rhs)
887 {
888   return lhs.m_data > rhs.m_data;
889 }
890 /**
891  * Compare a Time to an EventId.
892  *
893  * This is useful when you have cached a previously scheduled event:
894  *
895  *     m_event = Schedule (...);
896  *
897  * and later you want to know the relationship between that event
898  * and some other Time `when`:
899  *
900  *     if (when < m_event) ...
901  *
902  * \param [in] time The Time operand.
903  * \param [in] event The EventId
904  * \returns \c true if \p time is before (less than) the
905  *          time stamp of the EventId.
906  */
907 inline bool
908 operator <  (const Time & time, const EventId & event)
909 {
910   // Negative Time is less than any possible EventId, which are all >= 0.
911   if (time.m_data < 0)
912     {
913       return true;
914     }
915   // Time must be >= 0 so casting to unsigned is safe.
916   return static_cast<uint64_t> (time.m_data) < event.GetTs ();
917 }
918 /**
919  * Addition operator for Time.
920  * \param [in] lhs The first value
921  * \param [in] rhs The second value
922  * \returns The sum of the two input values.
923  */
924 inline Time operator + (const Time & lhs, const Time & rhs)
925 {
926   return Time (lhs.m_data + rhs.m_data);
927 }
928 /**
929  * Subtraction operator for Time.
930  * \param [in] lhs The first value
931  * \param [in] rhs The second value
932  * \returns The difference of the two input values.
933  */
934 inline Time operator - (const Time & lhs, const Time & rhs)
935 {
936   return Time (lhs.m_data - rhs.m_data);
937 }
938 
939 /**
940  * Scale a Time by a numeric value.
941  * \param [in] lhs The first value
942  * \param [in] rhs The second value
943  * \returns The Time scaled by the other operand.
944  */
945 inline Time
946 operator * (const Time & lhs, const int64x64_t & rhs)
947 {
948   int64x64_t res = lhs.m_data;
949   res *= rhs;
950   return Time (res);
951 }
952 /**
953  * Scale a Time by a numeric value.
954  * \param [in] lhs The first value
955  * \param [in] rhs The second value
956  * \returns The Time scaled by the other operand.
957  */
958 inline Time
959 operator * (const int64x64_t & lhs, const Time & rhs)
960 {
961   return rhs * lhs;
962 }
963 
964 /**
965  * Scale a Time by an integer value.
966  *
967  * \tparam T Integer data type (int, long, etc.)
968  *
969  * \param [in] lhs The Time instance to scale
970  * \param [in] rhs The scale value
971  * \returns A new Time instance containing the scaled value
972  */
973 template<class T>
974 typename std::enable_if<std::is_integral<T>::value, Time>::type
975 operator * (const Time& lhs, T rhs)
976 {
977   static_assert(!std::is_same<T, bool>::value,
978                 "Multiplying a Time by a boolean is not supported");
979 
980   return Time (lhs.m_data * rhs);
981 }
982 
983 /**
984  * Scale a Time by a numeric value.
985  *
986  * This overload handles the case where the scale value comes before the Time
987  * value.  It swaps the arguments so that the Time argument comes first
988  * and calls the appropriate overload of operator*
989  *
990  * \tparam T Arithmetic data type (int, long, float, etc.)
991  *
992  * \param [in] lhs The scale value
993  * \param [in] rhs The Time instance to scale
994  * \returns A new Time instance containing the scaled value
995  */
996 template<class T>
997 typename std::enable_if<std::is_arithmetic<T>::value, Time>::type
998 operator * (T lhs, const Time& rhs)
999 {
1000   return rhs * lhs;
1001 }
1002 
1003 /**
1004  * Scale a Time by a floating point value.
1005  *
1006  * \tparam T Floating point data type (float, double, etc.)
1007  *
1008  * \param [in] lhs The scale value
1009  * \param [in] rhs The Time instance to scale
1010  * \returns A new Time instance containing the scaled value
1011  */
1012 template<class T>
1013 typename std::enable_if<std::is_floating_point<T>::value, Time>::type
1014 operator * (const Time& lhs, T rhs)
1015 {
1016   return lhs * int64x64_t(rhs);
1017 }
1018 
1019 /**
1020  * Exact division, returning a dimensionless fixed point number.
1021  *
1022  * This can be truncated to integer, or converted to double
1023  * (with loss of precison).  Assuming `ta` and `tb` are Times:
1024  *
1025  * \code
1026  *     int64x64_t ratio = ta / tb;
1027  *
1028  *     int64_t i = ratio.GetHigh ();      // Get just the integer part, resulting in truncation
1029  *
1030  *     double ratioD = double (ratio);    // Convert to double, with loss of precision
1031  * \endcode
1032  *
1033  * \param [in] lhs The first value
1034  * \param [in] rhs The second value
1035  * \returns The exact ratio of the two operands.
1036  */
1037 inline int64x64_t
1038 operator / (const Time & lhs, const Time & rhs)
1039 {
1040   int64x64_t num = lhs.m_data;
1041   int64x64_t den = rhs.m_data;
1042   return num / den;
1043 }
1044 
1045 /**
1046  * Scale a Time by a numeric value.
1047  * \param [in] lhs The first value
1048  * \param [in] rhs The second value
1049  * \returns The Time divided by the scalar operand.
1050  */
1051 inline Time
1052 operator / (const Time & lhs, const int64x64_t & rhs)
1053 {
1054   int64x64_t res = lhs.m_data;
1055   res /= rhs;
1056   return Time (res);
1057 }
1058 
1059 /**
1060  * Divide a Time by an integer value.
1061  *
1062  * \tparam T Integer data type (int, long, etc.)
1063  *
1064  * \param [in] lhs The Time instance to scale
1065  * \param [in] rhs The scale value
1066  * \returns A new Time instance containing the scaled value
1067  */
1068 template<class T>
1069 typename std::enable_if<std::is_integral<T>::value, Time>::type
1070 operator / (const Time& lhs, T rhs)
1071 {
1072   static_assert(!std::is_same<T, bool>::value,
1073                 "Dividing a Time by a boolean is not supported");
1074 
1075   return Time(lhs.m_data / rhs);
1076 }
1077 
1078 /**
1079  * Divide a Time by a floating point value.
1080  *
1081  * \tparam T Floating point data type (float, double, etc.)
1082  *
1083  * \param [in] lhs The Time instance to scale
1084  * \param [in] rhs The scale value
1085  * \returns A new Time instance containing the scaled value
1086  */
1087 template<class T>
1088 typename std::enable_if<std::is_floating_point<T>::value, Time>::type
1089 operator / (const Time& lhs, T rhs)
1090 {
1091   return lhs / int64x64_t(rhs);
1092 }
1093 
1094 /**
1095  * Remainder (modulus) from the quotient of two Times.
1096  *
1097  * This is exactly the same function as Rem()
1098  *
1099  *     Rem (ta, tb)  ==  ta % tb;
1100  *
1101  * \see Div()
1102  * \param [in] lhs The first time value
1103  * \param [in] rhs The second time value
1104  * \returns The remainder of `lhs / rhs`.
1105  */
1106 inline Time
1107 operator % (const Time & lhs, const Time & rhs)
1108 {
1109   return Time (lhs.m_data % rhs.m_data);
1110 }
1111 /**
1112  * Integer quotient from dividing two Times.
1113  *
1114  * This is the same as the "normal" C++ integer division,
1115  * which truncates (discarding any remainder).
1116  *
1117  * As usual, if `ta`, and `tb` are both Times
1118  *
1119  * \code
1120  *     ta  ==  tb * Div (ta, tb) + Rem (ta, tb);
1121  *
1122  *     ta  ==  tb * (ta / tb).GetHigh()  + ta % tb;
1123  * \endcode
1124  *
1125  * \param [in] lhs The first value
1126  * \param [in] rhs The second value
1127  * \returns The integer portion of `lhs / rhs`.
1128  *
1129  * \see Rem()
1130  */
1131 inline int64_t
Div(const Time & lhs,const Time & rhs)1132 Div (const Time & lhs, const Time & rhs)
1133 {
1134   return lhs.m_data / rhs.m_data;
1135 }
1136 /**
1137  * Remainder (modulus) from the quotient of two Times.
1138  *
1139  * This is exactly the same function as operator%()
1140  *
1141  *     Rem (ta, tb)  ==  ta % tb;
1142  *
1143  * \see Div()
1144  * \param [in] lhs The first time value
1145  * \param [in] rhs The second time value
1146  * \returns The result of the remainder of the first input / second input value.
1147  */
1148 inline Time
Rem(const Time & lhs,const Time & rhs)1149 Rem (const Time & lhs, const Time & rhs)
1150 {
1151   return Time (lhs.m_data % rhs.m_data);
1152 }
1153 
1154 /**
1155  * Compound addition assignment for Time.
1156  * \param [in] lhs The first value
1157  * \param [in] rhs The second value
1158  * \returns The sum of the two inputs.
1159  */
1160 inline Time & operator += (Time & lhs, const Time & rhs)
1161 {
1162   lhs.m_data += rhs.m_data;
1163   return lhs;
1164 }
1165 /**
1166  * Compound subtraction assignment for Time.
1167  * \param [in] lhs The first value
1168  * \param [in] rhs The second value
1169  * \returns The difference of the two operands.
1170  */
1171 inline Time & operator -= (Time & lhs, const Time & rhs)
1172 {
1173   lhs.m_data -= rhs.m_data;
1174   return lhs;
1175 }
1176 /**
1177  * Absolute value for Time.
1178  * \param [in] time The Time value
1179  * \returns The absolute value of the input.
1180  */
Abs(const Time & time)1181 inline Time Abs (const Time & time)
1182 {
1183   return Time ((time.m_data < 0) ? -time.m_data : time.m_data);
1184 }
1185 /**
1186  * Maximum of two Times.
1187  * \param [in] timeA The first value
1188  * \param [in] timeB The second value
1189  * \returns The larger of the two operands.
1190  */
Max(const Time & timeA,const Time & timeB)1191 inline Time Max (const Time & timeA, const Time & timeB)
1192 {
1193   return Time ((timeA.m_data < timeB.m_data) ? timeB : timeA);
1194 }
1195 /**
1196  * Minimum of two Times.
1197  * \param [in] timeA The first value
1198  * \param [in] timeB The second value
1199  * \returns The smaller of the two operands.
1200  */
Min(const Time & timeA,const Time & timeB)1201 inline Time Min (const Time & timeA, const Time & timeB)
1202 {
1203   return Time ((timeA.m_data > timeB.m_data) ? timeB : timeA);
1204 }
1205 
1206 /**
1207  * Time output streamer.
1208  *
1209  * Generates output such as "396.0ns".
1210  *
1211  * For historical reasons Times are printed with the
1212  * following format flags (independent of the stream flags):
1213  *   - `showpos`
1214  *   - `fixed`
1215  *   - `left`
1216  *
1217  * The stream `width` and `precision` are ignored; Time output always
1218  * includes ".0".
1219  *
1220  * \see As() for more flexible output formatting.
1221  *
1222  * \param [in,out] os The output stream.
1223  * \param [in] time The Time to put on the stream.
1224  * \return The stream.
1225  */
1226 std::ostream & operator << (std::ostream & os, const Time & time);
1227 /**
1228  * Time input streamer
1229  *
1230  * Uses the Time(const std::string &) constructor
1231  *
1232  * \param [in,out] is The input stream.
1233  * \param [out] time The Time variable to set from the stream data.
1234  * \return The stream.
1235  */
1236 std::istream & operator >> (std::istream & is, Time & time);
1237 
1238 
1239 /**
1240  * \ingroup time
1241  * \defgroup timecivil Standard Time Units.
1242  * Convenience constructors in standard units.
1243  *
1244  * For example:
1245  * \code
1246  *   Time t = Seconds (2.0);
1247  *   Simulator::Schedule (Seconds (5.0), ...);
1248  * \endcode
1249  */
1250 /**
1251  * \ingroup timecivil
1252  * Construct a Time in the indicated unit.
1253  * \param [in] value The value
1254  * \return The Time
1255  * @{
1256  */
Years(double value)1257 inline Time Years (double value)
1258 {
1259   return Time::FromDouble (value, Time::Y);
1260 }
Years(int64x64_t value)1261 inline Time Years (int64x64_t value)
1262 {
1263   return Time::From (value, Time::Y);
1264 }
Days(double value)1265 inline Time Days (double value)
1266 {
1267   return Time::FromDouble (value, Time::D);
1268 }
Days(int64x64_t value)1269 inline Time Days (int64x64_t value)
1270 {
1271   return Time::From (value, Time::D);
1272 }
Hours(double value)1273 inline Time Hours (double value)
1274 {
1275   return Time::FromDouble (value, Time::H);
1276 }
Hours(int64x64_t value)1277 inline Time Hours (int64x64_t value)
1278 {
1279   return Time::From (value, Time::H);
1280 }
Minutes(double value)1281 inline Time Minutes (double value)
1282 {
1283   return Time::FromDouble (value, Time::MIN);
1284 }
Minutes(int64x64_t value)1285 inline Time Minutes (int64x64_t value)
1286 {
1287   return Time::From (value, Time::MIN);
1288 }
Seconds(double value)1289 inline Time Seconds (double value)
1290 {
1291   return Time::FromDouble (value, Time::S);
1292 }
Seconds(int64x64_t value)1293 inline Time Seconds (int64x64_t value)
1294 {
1295   return Time::From (value, Time::S);
1296 }
MilliSeconds(uint64_t value)1297 inline Time MilliSeconds (uint64_t value)
1298 {
1299   return Time::FromInteger (value, Time::MS);
1300 }
MilliSeconds(int64x64_t value)1301 inline Time MilliSeconds (int64x64_t value)
1302 {
1303   return Time::From (value, Time::MS);
1304 }
MicroSeconds(uint64_t value)1305 inline Time MicroSeconds (uint64_t value)
1306 {
1307   return Time::FromInteger (value, Time::US);
1308 }
MicroSeconds(int64x64_t value)1309 inline Time MicroSeconds (int64x64_t value)
1310 {
1311   return Time::From (value, Time::US);
1312 }
NanoSeconds(uint64_t value)1313 inline Time NanoSeconds (uint64_t value)
1314 {
1315   return Time::FromInteger (value, Time::NS);
1316 }
NanoSeconds(int64x64_t value)1317 inline Time NanoSeconds (int64x64_t value)
1318 {
1319   return Time::From (value, Time::NS);
1320 }
PicoSeconds(uint64_t value)1321 inline Time PicoSeconds (uint64_t value)
1322 {
1323   return Time::FromInteger (value, Time::PS);
1324 }
PicoSeconds(int64x64_t value)1325 inline Time PicoSeconds (int64x64_t value)
1326 {
1327   return Time::From (value, Time::PS);
1328 }
FemtoSeconds(uint64_t value)1329 inline Time FemtoSeconds (uint64_t value)
1330 {
1331   return Time::FromInteger (value, Time::FS);
1332 }
FemtoSeconds(int64x64_t value)1333 inline Time FemtoSeconds (int64x64_t value)
1334 {
1335   return Time::From (value, Time::FS);
1336 }
1337 /**@}*/  // Construct a Time in the indicated unit.
1338 
1339 
1340 /**
1341  * Scheduler interface.
1342  *
1343  * \note This is internal to the Time implementation.
1344  * \param [in] ts The time value, in the current unit.
1345  * \return A Time.
1346  * \relates Time
1347  */
TimeStep(uint64_t ts)1348 inline Time TimeStep (uint64_t ts)
1349 {
1350   return Time (ts);
1351 }
1352 
1353 ATTRIBUTE_VALUE_DEFINE (Time);
1354 ATTRIBUTE_ACCESSOR_DEFINE (Time);
1355 
1356 /**
1357  *  \ingroup attribute_time
1358  *  Helper to make a Time checker with bounded range.
1359  *  Both limits are inclusive
1360  *
1361  * \param [in] min Minimum allowed value.
1362  * \param [in] max Maximum allowed value.
1363  * \return The AttributeChecker
1364  */
1365 Ptr<const AttributeChecker> MakeTimeChecker (const Time min, const Time max);
1366 
1367 /**
1368  * \ingroup attribute_time
1369  * Helper to make an unbounded Time checker.
1370  *
1371  * \return The AttributeChecker
1372  */
1373 inline
MakeTimeChecker(void)1374 Ptr<const AttributeChecker> MakeTimeChecker (void)
1375 {
1376   return MakeTimeChecker (Time::Min (), Time::Max ());
1377 }
1378 
1379 /**
1380  * \ingroup attribute_time
1381  * Helper to make a Time checker with a lower bound.
1382  *
1383  *  \param [in] min Minimum allowed value.
1384  * \return The AttributeChecker
1385  */
1386 inline
MakeTimeChecker(const Time min)1387 Ptr<const AttributeChecker> MakeTimeChecker (const Time min)
1388 {
1389   return MakeTimeChecker (min, Time::Max ());
1390 }
1391 
1392 /**
1393  * \ingroup time
1394  * A Time with attached unit, to facilitate output in that unit.
1395  */
1396 class TimeWithUnit
1397 {
1398 public:
1399   /**
1400    * Attach a unit to a Time
1401    *
1402    * \param [in] time The time.
1403    * \param [in] unit The unit to use for output
1404    */
TimeWithUnit(const Time time,const Time::Unit unit)1405   TimeWithUnit (const Time time, const Time::Unit unit)
1406     : m_time (time),
1407       m_unit (unit)
1408   { }
1409 
1410 private:
1411   Time m_time;        //!< The time
1412   Time::Unit m_unit;  //!< The unit to use in output
1413 
1414   /**
1415    *  Output streamer
1416    *  \param [in,out] os The stream.
1417    *  \param [in] timeU The Time with desired unit
1418    *  \returns The stream.
1419    */
1420   friend std::ostream & operator << (std::ostream & os, const TimeWithUnit & timeU);
1421 
1422 };  // class TimeWithUnit
1423 
1424 } // namespace ns3
1425 
1426 #endif /* TIME_H */
1427