src/core/model/nstime.h
changeset 10857 a1e09c7953a1
parent 10784 13017af6d1b0
child 10978 754c8256c35c
equal deleted inserted replaced
10856:d45187afb01a 10857:a1e09c7953a1
    35 
    35 
    36 class TimeWithUnit;
    36 class TimeWithUnit;
    37   
    37   
    38 /**
    38 /**
    39  * \ingroup core
    39  * \ingroup core
       
    40  * \defgroup time Virtual Time
       
    41  * \brief Management of virtual time in real world units.
       
    42  *
       
    43  * The underlying simulator is unit agnostic, just dealing with
       
    44  * dimensionless virtual time.  Models usually need to handle
       
    45  * time in real world units, such as seconds, and conversions/scaling
       
    46  * between different units, between minutes and seconds, for example.
       
    47  *
       
    48  * The convenience constructors in the \ref timecivil "Standard Units" module
       
    49  * make it easy to create Times in specific units.
       
    50  *
       
    51  * The Time::SetResolution() function allows a one-time change of the
       
    52  * base resolution, before Simulator::Run().
       
    53  */
       
    54 /**
       
    55  * \ingroup time
    40  * \brief Simulation virtual time values and global simulation resolution.
    56  * \brief Simulation virtual time values and global simulation resolution.
    41  *
    57  *
    42  * This class defines all the classic C++ addition/subtraction
    58  * This class defines all the classic C++ addition/subtraction
    43  * operators: +, -, +=, -=; and all the classic comparison operators:
    59  * operators: +, -, +=, -=; and all the classic comparison operators:
    44  * ==, !=, <, >, <=, >=. It is thus easy to add, substract, or
    60  * ==, !=, <, >, <=, >=. It is thus easy to add, substract, or
    95     PS  = 8,   //!< picosecond
   111     PS  = 8,   //!< picosecond
    96     FS  = 9,   //!< femtosecond
   112     FS  = 9,   //!< femtosecond
    97     LAST = 10
   113     LAST = 10
    98   };
   114   };
    99 
   115 
       
   116   /**
       
   117    *  Assignment operator
       
   118    * \param [in] o Time to assign.
       
   119    * \return the Time.
       
   120    */      
   100   inline Time & operator = (const Time & o)
   121   inline Time & operator = (const Time & o)
   101   {
   122   {
   102     m_data = o.m_data;
   123     m_data = o.m_data;
   103     return *this;
   124     return *this;
   104   }
   125   }
       
   126   /** Default constructor, with value 0. */
   105   inline Time ()
   127   inline Time ()
   106     : m_data ()
   128     : m_data ()
   107   {
   129   {
   108     if (g_markingTimes)
   130     if (g_markingTimes)
   109       {
   131       {
   110 	Mark (this);
   132 	Mark (this);
   111       }
   133       }
   112   }
   134   }
       
   135   /**
       
   136    *  Copy constructor
       
   137    *
       
   138    * \param [in] o Time to copy
       
   139    */      
   113   inline Time(const Time & o)
   140   inline Time(const Time & o)
   114     : m_data (o.m_data)
   141     : m_data (o.m_data)
   115   {
   142   {
   116     if (g_markingTimes)
   143     if (g_markingTimes)
   117       {
   144       {
   118 	Mark (this);
   145 	Mark (this);
   119       }
   146       }
   120   }
   147   }
       
   148   /**
       
   149    *  Construct from a numeric value.
       
   150    *
       
   151    *  The current time resolution will be assumed as the unit.
       
   152    *  \param [in] v The value.
       
   153    *  @{
       
   154    */
   121   explicit inline Time (double v)
   155   explicit inline Time (double v)
   122     : m_data (lround (v))
   156     : m_data (lround (v))
   123   {
   157   {
   124     if (g_markingTimes)
   158     if (g_markingTimes)
   125       {
   159       {
   172     if (g_markingTimes)
   206     if (g_markingTimes)
   173       {
   207       {
   174 	Mark (this);
   208 	Mark (this);
   175       }
   209       }
   176   }
   210   }
       
   211   explicit inline Time (const int64x64_t & v)
       
   212     : m_data (v.GetHigh ())
       
   213   {
       
   214     if (g_markingTimes)
       
   215       {
       
   216 	Mark (this);
       
   217       }
       
   218   }
       
   219   /**@}*/
       
   220   
   177   /**
   221   /**
   178    * \brief Construct Time object from common time expressions like "1ms"
   222    * \brief Construct Time object from common time expressions like "1ms"
   179    *
   223    *
   180    * Supported units include:
   224    * Supported units include:
   181    * - `s`  (seconds)
   225    * - `s`  (seconds)
   194    * occur.
   238    * occur.
   195    * \param s The string to parse into a Time
   239    * \param s The string to parse into a Time
   196    */
   240    */
   197   explicit Time (const std::string & s);
   241   explicit Time (const std::string & s);
   198 
   242 
   199   /**
   243   /** Minimum representable Time */
   200    * \brief Minimum representable Time
       
   201    */
       
   202   static Time Min ()
   244   static Time Min ()
   203   {
   245   {
   204     return Time (std::numeric_limits<int64_t>::min ());
   246     return Time (std::numeric_limits<int64_t>::min ());
   205   }
   247   }
   206   /**
   248   /** Maximum representable Time */
   207    * \brief Maximum representable Time
       
   208    */
       
   209   static Time Max ()
   249   static Time Max ()
   210   {
   250   {
   211     return Time (std::numeric_limits<int64_t>::max ());
   251     return Time (std::numeric_limits<int64_t>::max ());
   212   }
   252   }
   213 
   253 
   214   /**
   254   /** Destructor */
   215    *  Destructor
       
   216    */
       
   217   ~Time ()
   255   ~Time ()
   218   {
   256   {
   219     if (g_markingTimes)
   257     if (g_markingTimes)
   220       {
   258       {
   221         Clear (this);
   259         Clear (this);
   222       }
   260       }
   223   }
   261   }
   224 
   262 
   225   /**
   263   /** \return true if the time is zero, false otherwise. */
   226    * \return true if the time is zero, false otherwise.
       
   227    */
       
   228   inline bool IsZero (void) const
   264   inline bool IsZero (void) const
   229   {
   265   {
   230     return m_data == 0;
   266     return m_data == 0;
   231   }
   267   }
   232   /**
   268   /** \return true if the time is negative or zero, false otherwise. */
   233    * \return true if the time is negative or zero, false otherwise.
       
   234    */
       
   235   inline bool IsNegative (void) const
   269   inline bool IsNegative (void) const
   236   {
   270   {
   237     return m_data <= 0;
   271     return m_data <= 0;
   238   }
   272   }
   239   /**
   273   /** \return true if the time is positive or zero, false otherwise. */
   240    * \return true if the time is positive or zero, false otherwise.
       
   241    */
       
   242   inline bool IsPositive (void) const
   274   inline bool IsPositive (void) const
   243   {
   275   {
   244     return m_data >= 0;
   276     return m_data >= 0;
   245   }
   277   }
   246   /**
   278   /** \return true if the time is strictly negative, false otherwise. */
   247    * \return true if the time is strictly negative, false otherwise.
       
   248    */
       
   249   inline bool IsStrictlyNegative (void) const
   279   inline bool IsStrictlyNegative (void) const
   250   {
   280   {
   251     return m_data < 0;
   281     return m_data < 0;
   252   }
   282   }
   253   /**
   283   /** \return true if the time is strictly positive, false otherwise. */
   254    * \return true if the time is strictly positive, false otherwise.
       
   255    */
       
   256   inline bool IsStrictlyPositive (void) const
   284   inline bool IsStrictlyPositive (void) const
   257   {
   285   {
   258     return m_data > 0;
   286     return m_data > 0;
   259   }
   287   }
   260   /**
   288   /**
       
   289    *  Compare \p this to another Time
       
   290    *
       
   291    *  \param [in] o The other Time
   261    *  \return -1,0,+1 if `this < o`, `this == o`, or `this > o`
   292    *  \return -1,0,+1 if `this < o`, `this == o`, or `this > o`
   262    */
   293    */
   263   inline int Compare (const Time & o) const
   294   inline int Compare (const Time & o) const
   264   {
   295   {
   265     return (m_data < o.m_data) ? -1 : (m_data == o.m_data) ? 0 : 1;
   296     return (m_data < o.m_data) ? -1 : (m_data == o.m_data) ? 0 : 1;
   266   }
   297   }
   267 
   298 
   268   /**
   299   /**
   269    * \returns an approximation in seconds of the time stored in this
   300    * Get an approximation of the time stored in this instance
   270    *          instance.
   301    * in the indicated unit.
   271    */
   302    *
       
   303    * \return An approximate value in the indicated unit.
       
   304    * @{
       
   305    */
       
   306   inline double GetYears (void) const
       
   307   {
       
   308     return ToDouble (Time::Y);
       
   309   }
       
   310   inline double GetDays (void) const
       
   311   {
       
   312     return ToDouble (Time::D);
       
   313   }
       
   314   inline double GetHours (void) const
       
   315   {
       
   316     return ToDouble (Time::H);
       
   317   }
       
   318   inline double GetMinutes (void) const
       
   319   {
       
   320     return ToDouble (Time::MIN);
       
   321   }
   272   inline double GetSeconds (void) const
   322   inline double GetSeconds (void) const
   273   {
   323   {
   274     return ToDouble (Time::S);
   324     return ToDouble (Time::S);
   275   }
   325   }
   276 
       
   277   /**
       
   278    * \returns an approximation in milliseconds of the time stored in this
       
   279    *          instance.
       
   280    */
       
   281   inline int64_t GetMilliSeconds (void) const
   326   inline int64_t GetMilliSeconds (void) const
   282   {
   327   {
   283     return ToInteger (Time::MS);
   328     return ToInteger (Time::MS);
   284   }
   329   }
   285   /**
       
   286    * \returns an approximation in microseconds of the time stored in this
       
   287    *          instance.
       
   288    */
       
   289   inline int64_t GetMicroSeconds (void) const
   330   inline int64_t GetMicroSeconds (void) const
   290   {
   331   {
   291     return ToInteger (Time::US);
   332     return ToInteger (Time::US);
   292   }
   333   }
   293   /**
       
   294    * \returns an approximation in nanoseconds of the time stored in this
       
   295    *          instance.
       
   296    */
       
   297   inline int64_t GetNanoSeconds (void) const
   334   inline int64_t GetNanoSeconds (void) const
   298   {
   335   {
   299     return ToInteger (Time::NS);
   336     return ToInteger (Time::NS);
   300   }
   337   }
   301   /**
       
   302    * \returns an approximation in picoseconds of the time stored in this
       
   303    *          instance.
       
   304    */
       
   305   inline int64_t GetPicoSeconds (void) const
   338   inline int64_t GetPicoSeconds (void) const
   306   {
   339   {
   307     return ToInteger (Time::PS);
   340     return ToInteger (Time::PS);
   308   }
   341   }
   309   /**
       
   310    * \returns an approximation in femtoseconds of the time stored in this
       
   311    *          instance.
       
   312    */
       
   313   inline int64_t GetFemtoSeconds (void) const
   342   inline int64_t GetFemtoSeconds (void) const
   314   {
   343   {
   315     return ToInteger (Time::FS);
   344     return ToInteger (Time::FS);
   316   }
   345   }
   317 
   346   /**@}*/
   318   /**
   347 
   319    * \returns an approximation in minutes of the time stored in this
   348   /**
   320    *          instance.
   349    * \returns the raw time value, in the current unit
   321    */
   350    * @{
   322   inline double GetMinutes (void) const
       
   323   {
       
   324     return ToDouble (Time::MIN);
       
   325   }
       
   326   /**
       
   327    * \returns an approximation in hours of the time stored in this
       
   328    *          instance.
       
   329    */
       
   330   inline double GetHours (void) const
       
   331   {
       
   332     return ToDouble (Time::H);
       
   333   }
       
   334   /**
       
   335    * \returns an approximation in days of the time stored in this
       
   336    *          instance.
       
   337    */
       
   338   inline double GetDays (void) const
       
   339   {
       
   340     return ToDouble (Time::D);
       
   341   }
       
   342   /**
       
   343    * \returns an approximation in years of the time stored in this
       
   344    *          instance.
       
   345    */
       
   346   inline double GetYears (void) const
       
   347   {
       
   348     return ToDouble (Time::Y);
       
   349   }
       
   350 
       
   351   /**
       
   352    * \returns the raw time value, in the current units
       
   353    */
   351    */
   354   inline int64_t GetTimeStep (void) const
   352   inline int64_t GetTimeStep (void) const
   355   {
   353   {
   356     return m_data;
   354     return m_data;
   357   }
   355   }
   361   }
   359   }
   362   inline int64_t GetInteger (void) const
   360   inline int64_t GetInteger (void) const
   363   {
   361   {
   364     return GetTimeStep ();
   362     return GetTimeStep ();
   365   }
   363   }
       
   364   /**@}*/
   366 
   365 
   367 
   366 
   368   /**
   367   /**
   369    * \param resolution the new resolution to use
   368    * \param resolution the new resolution to use
   370    *
   369    *
   375   static void SetResolution (enum Unit resolution);
   374   static void SetResolution (enum Unit resolution);
   376   /**
   375   /**
   377    * \returns the current global resolution.
   376    * \returns the current global resolution.
   378    */
   377    */
   379   static enum Unit GetResolution (void);
   378   static enum Unit GetResolution (void);
   380   /**
   379 
   381    * \param value to convert into a Time object
   380   
   382    * \param timeUnit the unit of the value to convert
   381   /**
   383    * \return a new Time object
   382    *  Create a Time in the current unit.
   384    *
   383    *
   385    * This method interprets the input value according to the input
   384    *  \param [in] value The value of the new Time.
   386    * unit and constructs a matching Time object.
   385    *  \return A Time with \p value in the current time unit.
   387    *
   386    */
   388    * \sa FromDouble, ToDouble, ToInteger
   387   inline static Time From (const int64x64_t & value)
   389    */
   388   {
   390   inline static Time FromInteger (uint64_t value, enum Unit timeUnit)
   389     return Time (value);
   391   {
   390   }
   392     struct Information *info = PeekInformation (timeUnit);
   391   /**
       
   392    *  Create a Time equal to \p value  in unit \c unit
       
   393    *
       
   394    *  \param [in] value The new Time value, expressed in \c unit
       
   395    *  \param [in] unit The unit of \p value
       
   396    *  \return The Time representing \p value in \c unit
       
   397    *  @{
       
   398    */
       
   399   inline static Time FromInteger (uint64_t value, enum Unit unit)
       
   400   {
       
   401     struct Information *info = PeekInformation (unit);
   393     if (info->fromMul)
   402     if (info->fromMul)
   394       {
   403       {
   395         value *= info->factor;
   404         value *= info->factor;
   396       }
   405       }
   397     else
   406     else
   398       {
   407       {
   399         value /= info->factor;
   408         value /= info->factor;
   400       }
   409       }
   401     return Time (value);
   410     return Time (value);
   402   }
   411   }
   403   /**
   412   inline static Time FromDouble (double value, enum Unit unit)
   404    * \param timeUnit the unit of the value to return
   413   {
   405    * \return int64_t time value
   414     return From (int64x64_t (value), unit);
   406    *
   415   }
   407    * Convert the input time into an integer value according to the requested
   416   inline static Time From (const int64x64_t & value, enum Unit unit)
   408    * time unit.
   417   {
   409    */
   418     struct Information *info = PeekInformation (unit);
   410   inline int64_t ToInteger (enum Unit timeUnit) const
   419     // DO NOT REMOVE this temporary variable. It's here
   411   {
   420     // to work around a compiler bug in gcc 3.4
   412     struct Information *info = PeekInformation (timeUnit);
   421     int64x64_t retval = value;
       
   422     if (info->fromMul)
       
   423       {
       
   424         retval *= info->timeFrom;
       
   425       }
       
   426     else
       
   427       {
       
   428         retval.MulByInvert (info->timeFrom);
       
   429       }
       
   430     return Time (retval);
       
   431   }
       
   432   /**@}*/
       
   433 
       
   434   
       
   435   /**
       
   436    *  Get the Time value expressed in a particular unit.
       
   437    *
       
   438    *  \param [in] unit The desired unit
       
   439    *  \return The Time expressed in \p unit
       
   440    *  @{
       
   441    */
       
   442   inline int64_t ToInteger (enum Unit unit) const
       
   443   {
       
   444     struct Information *info = PeekInformation (unit);
   413     int64_t v = m_data;
   445     int64_t v = m_data;
   414     if (info->toMul)
   446     if (info->toMul)
   415       {
   447       {
   416         v *= info->factor;
   448         v *= info->factor;
   417       }
   449       }
   419       {
   451       {
   420         v /= info->factor;
   452         v /= info->factor;
   421       }
   453       }
   422     return v;
   454     return v;
   423   }
   455   }
   424   /**
   456   inline double ToDouble (enum Unit unit) const
   425    * \param value to convert into a Time object
   457   {
   426    * \param timeUnit the unit of the value to convert
   458     return To (unit).GetDouble ();
   427    * \return a new Time object
   459   }
   428    *
   460   inline int64x64_t To (enum Unit unit) const
   429    * \sa FromInteger, ToInteger, ToDouble
   461   {
   430    */
   462     struct Information *info = PeekInformation (unit);
   431   inline static Time FromDouble (double value, enum Unit timeUnit)
       
   432   {
       
   433     return From (int64x64_t (value), timeUnit);
       
   434   }
       
   435   /**
       
   436    * \param timeUnit the unit of the value to return
       
   437    * \return double time value
       
   438    *
       
   439    * Convert the input time into a floating point value according to the requested
       
   440    * time unit.
       
   441    */
       
   442   inline double ToDouble (enum Unit timeUnit) const
       
   443   {
       
   444     return To (timeUnit).GetDouble ();
       
   445   }
       
   446   static inline Time From (const int64x64_t & from, enum Unit timeUnit)
       
   447   {
       
   448     struct Information *info = PeekInformation (timeUnit);
       
   449     // DO NOT REMOVE this temporary variable. It's here
       
   450     // to work around a compiler bug in gcc 3.4
       
   451     int64x64_t retval = from;
       
   452     if (info->fromMul)
       
   453       {
       
   454         retval *= info->timeFrom;
       
   455       }
       
   456     else
       
   457       {
       
   458         retval.MulByInvert (info->timeFrom);
       
   459       }
       
   460     return Time (retval);
       
   461   }
       
   462   inline int64x64_t To (enum Unit timeUnit) const
       
   463   {
       
   464     struct Information *info = PeekInformation (timeUnit);
       
   465     int64x64_t retval = int64x64_t (m_data);
   463     int64x64_t retval = int64x64_t (m_data);
   466     if (info->toMul)
   464     if (info->toMul)
   467       {
   465       {
   468         retval *= info->timeTo;
   466         retval *= info->timeTo;
   469       }
   467       }
   471       {
   469       {
   472         retval.MulByInvert (info->timeTo);
   470         retval.MulByInvert (info->timeTo);
   473       }
   471       }
   474     return retval;
   472     return retval;
   475   }
   473   }
       
   474   /**@}*/
       
   475 
       
   476   
       
   477   /** Cast to int64x64_t */
   476   inline operator int64x64_t () const
   478   inline operator int64x64_t () const
   477   {
   479   {
   478     return int64x64_t (m_data);
   480     return int64x64_t (m_data);
   479   }
   481   }
   480   explicit inline Time (const int64x64_t & value)
   482 
   481     : m_data (value.GetHigh ())
   483   
   482   {
       
   483     if (g_markingTimes)
       
   484       {
       
   485 	Mark (this);
       
   486       }
       
   487   }
       
   488   inline static Time From (const int64x64_t & value)
       
   489   {
       
   490     return Time (value);
       
   491   }
       
   492 
       
   493   /**
   484   /**
   494    * Attach a unit to a Time, to facilitate output in a specific unit.
   485    * Attach a unit to a Time, to facilitate output in a specific unit.
   495    *
   486    *
   496    * For example,
   487    * For example,
   497    * \code
   488    * \code
   499    *   std::cout << t.As (Time::MS) << std::endl;
   490    *   std::cout << t.As (Time::MS) << std::endl;
   500    * \endcode
   491    * \endcode
   501    * will print ``+3140.0ms``
   492    * will print ``+3140.0ms``
   502    *
   493    *
   503    * \param unit [in] The unit to use.
   494    * \param unit [in] The unit to use.
       
   495    * \return The Time with embedded unit.
   504    */
   496    */
   505   TimeWithUnit As (const enum Unit unit) const;
   497   TimeWithUnit As (const enum Unit unit) const;
   506 
   498 
   507 private:
   499 private:
   508   /**
   500   /** How to convert between other units and the current unit. */
   509    * How to convert between other units and the current unit
       
   510    */
       
   511   struct Information
   501   struct Information
   512   {
   502   {
   513     bool toMul;                     //!< Multiply when converting To, otherwise divide
   503     bool toMul;                     //!< Multiply when converting To, otherwise divide
   514     bool fromMul;                   //!< Multiple when converting From, otherwise divide
   504     bool fromMul;                   //!< Multiple when converting From, otherwise divide
   515     int64_t factor;                 //!< Ratio of this unit / current unit
   505     int64_t factor;                 //!< Ratio of this unit / current unit
   516     int64x64_t timeTo;              //!< Multiplier to convert to this unit
   506     int64x64_t timeTo;              //!< Multiplier to convert to this unit
   517     int64x64_t timeFrom;            //!< Multiplier to convert from this unit
   507     int64x64_t timeFrom;            //!< Multiplier to convert from this unit
   518   };
   508   };
   519   /**
   509   /** Current time unit, and conversion info. */
   520    * Current time unit, and conversion info.
       
   521    */
       
   522   struct Resolution
   510   struct Resolution
   523   {
   511   {
   524     struct Information info[LAST];  //!<  Conversion info from current unit
   512     struct Information info[LAST];  //!<  Conversion info from current unit
   525     enum Time::Unit unit;           //!<  Current time unit
   513     enum Time::Unit unit;           //!<  Current time unit
   526   };
   514   };
   527 
   515 
       
   516   /**
       
   517    *  Get the current Resolution
       
   518    *
       
   519    * \return A pointer to the current Resolution
       
   520    */
   528   static inline struct Resolution *PeekResolution (void)
   521   static inline struct Resolution *PeekResolution (void)
   529   {
   522   {
   530     static struct Time::Resolution resolution = SetDefaultNsResolution ();
   523     static struct Time::Resolution resolution = SetDefaultNsResolution ();
   531     return & resolution;
   524     return & resolution;
   532   }
   525   }
       
   526   /**
       
   527    *  Get the Information record for \p timeUnit for the current Resolution
       
   528    *
       
   529    *  \param [in] timeUnit The Unit to get Information for
       
   530    *  \return the Information for \p timeUnit
       
   531    */
   533   static inline struct Information *PeekInformation (enum Unit timeUnit)
   532   static inline struct Information *PeekInformation (enum Unit timeUnit)
   534   {
   533   {
   535     return & (PeekResolution ()->info[timeUnit]);
   534     return & (PeekResolution ()->info[timeUnit]);
   536   }
   535   }
   537 
   536 
       
   537   /**
       
   538    *  Set the default resolution
       
   539    *
       
   540    * \return The Resolution object for the default resolution.
       
   541    */
   538   static struct Resolution SetDefaultNsResolution (void);
   542   static struct Resolution SetDefaultNsResolution (void);
       
   543   /**
       
   544    *  Set the current Resolution.
       
   545    *
       
   546    *  \param [in] unit The unit to use as the new resolution.
       
   547    *  \param [in,out] resolution The Resolution record to update.
       
   548    *  \param [in] convert Whether to convert existing Time objects to the new resolution.
       
   549    */
   539   static void SetResolution (enum Unit unit, struct Resolution *resolution,
   550   static void SetResolution (enum Unit unit, struct Resolution *resolution,
   540                              const bool convert = true);
   551                              const bool convert = true);
   541 
   552 
   542   /**
   553   /**
   543    *  Record all instances of Time, so we can rescale them when
   554    *  Record all instances of Time, so we can rescale them when
   574    *  includes nstime.h.
   585    *  includes nstime.h.
   575    */
   586    */
   576   static MarkedTimes * g_markingTimes;
   587   static MarkedTimes * g_markingTimes;
   577 public:
   588 public:
   578   /**
   589   /**
   579    *  Function to force static initialization of Time
   590    *  Function to force static initialization of Time.
       
   591    *
       
   592    * \return true on the first call
   580    */
   593    */
   581   static bool StaticInit ();
   594   static bool StaticInit ();
   582 private:
   595 private:
   583 
   596 
   584   /* Friend the Simulator class so it can call the private function
   597   /* Friend the Simulator class so it can call the private function
   591    *  \internal
   604    *  \internal
   592    *  Has to be visible to the Simulator class, hence the friending.
   605    *  Has to be visible to the Simulator class, hence the friending.
   593    */
   606    */
   594   static void ClearMarkedTimes ();
   607   static void ClearMarkedTimes ();
   595   /**
   608   /**
   596    *  Record a Time instance with the MarkedTimes
   609    *  Record a Time instance with the MarkedTimes.
       
   610    *  \param [in] time The Time instance to record.
   597    */
   611    */
   598   static void Mark (Time * const time);
   612   static void Mark (Time * const time);
   599   /**
   613   /**
   600    *  Remove a Time instance from the MarkedTimes, called by ~Time()
   614    *  Remove a Time instance from the MarkedTimes, called by ~Time().
       
   615    *  \param [in] time The Time instance to remove.
   601    */
   616    */
   602   static void Clear (Time * const time);
   617   static void Clear (Time * const time);
   603   /**
   618   /**
   604    *  Convert existing Times to the new unit.
   619    *  Convert existing Times to the new unit.
       
   620    *  \param [in] unit The Unit to convert existing Times to.
   605    */
   621    */
   606   static void ConvertTimes (const enum Unit unit);
   622   static void ConvertTimes (const enum Unit unit);
   607 
   623 
       
   624   /**
       
   625    *  @{
       
   626    *  Arithmetic operator.
       
   627    *  \param [in] lhs Left hand argument
       
   628    *  \param [in] rhs Righ hand argument
       
   629    *  \return The result of the operator.
       
   630    */
   608   friend bool operator == (const Time & lhs, const Time & rhs);
   631   friend bool operator == (const Time & lhs, const Time & rhs);
   609   friend bool operator != (const Time & lhs, const Time & rhs);
   632   friend bool operator != (const Time & lhs, const Time & rhs);
   610   friend bool operator <= (const Time & lhs, const Time & rhs);
   633   friend bool operator <= (const Time & lhs, const Time & rhs);
   611   friend bool operator >= (const Time & lhs, const Time & rhs);
   634   friend bool operator >= (const Time & lhs, const Time & rhs);
   612   friend bool operator < (const Time & lhs, const Time & rhs);
   635   friend bool operator < (const Time & lhs, const Time & rhs);
   617   friend Time operator * (const int64_t & lhs, const Time & rhs);
   640   friend Time operator * (const int64_t & lhs, const Time & rhs);
   618   friend int64_t operator / (const Time & lhs, const Time & rhs);
   641   friend int64_t operator / (const Time & lhs, const Time & rhs);
   619   friend Time operator / (const Time & lhs, const int64_t & rhs);
   642   friend Time operator / (const Time & lhs, const int64_t & rhs);
   620   friend Time & operator += (Time & lhs, const Time & rhs);
   643   friend Time & operator += (Time & lhs, const Time & rhs);
   621   friend Time & operator -= (Time & lhs, const Time & rhs);
   644   friend Time & operator -= (Time & lhs, const Time & rhs);
       
   645   /**@}*/
       
   646   
       
   647   /**
       
   648    *  Absolute value function for Time
       
   649    *  \param time the input value
       
   650    *  \returns the absolute value of the input value.
       
   651    */
   622   friend Time Abs (const Time & time);
   652   friend Time Abs (const Time & time);
       
   653   /**
       
   654    *  Max function for Time.
       
   655    *  \param ta the first value
       
   656    *  \param tb the seconds value
       
   657    *  \returns the max of the two input values.
       
   658    */
   623   friend Time Max (const Time & ta, const Time & tb);
   659   friend Time Max (const Time & ta, const Time & tb);
       
   660   /**
       
   661    *  Min function for Time.
       
   662    *  \param ta the first value
       
   663    *  \param tb the seconds value
       
   664    *  \returns the min of the two input values.
       
   665    */
   624   friend Time Min (const Time & ta, const Time & tb);
   666   friend Time Min (const Time & ta, const Time & tb);
   625 
   667 
   626 
   668   int64_t m_data;  //!< Virtual time value, in the current unit.
   627   int64_t m_data;                   //!< Virtual time value, in the current unit.
       
   628 
   669 
   629 };  // class Time
   670 };  // class Time
   630 
   671 
   631 
   672 
   632 /// Force static initialization of Time
   673 /// Force static initialization of Time
   706 {
   747 {
   707   lhs.m_data -= rhs.m_data;
   748   lhs.m_data -= rhs.m_data;
   708   return lhs;
   749   return lhs;
   709 }
   750 }
   710 
   751 
   711 /**
   752   
   712  * Max function for Time.
   753 inline Time Abs (const Time & time)
   713  * \param ta the first value
   754 {
   714  * \param tb the seconds value
   755   return Time ((time.m_data < 0) ? -time.m_data : time.m_data);
   715  * \returns the max of the two input values.
   756 }
   716  */
       
   717 inline Time Max (const Time & ta, const Time & tb)
   757 inline Time Max (const Time & ta, const Time & tb)
   718 {
   758 {
   719   return Time ((ta.m_data < tb.m_data) ? tb : ta);
   759   return Time ((ta.m_data < tb.m_data) ? tb : ta);
   720 }
   760 }
   721 /**
       
   722  * Min function for Time.
       
   723  * \param ta the first value
       
   724  * \param tb the seconds value
       
   725  * \returns the min of the two input values.
       
   726  */
       
   727 inline Time Min (const Time & ta, const Time & tb)
   761 inline Time Min (const Time & ta, const Time & tb)
   728 {
   762 {
   729   return Time ((ta.m_data > tb.m_data) ? tb : ta);
   763   return Time ((ta.m_data > tb.m_data) ? tb : ta);
   730 }
   764 }
   731 
   765 
   732 /**
   766 /**
   733  * Absolute value function for Time
   767  * \ingroup time
   734  * \param time the input value
       
   735  * \returns the absolute value of the input value.
       
   736  */
       
   737 inline Time Abs (const Time & time)
       
   738 {
       
   739   return Time ((time.m_data < 0) ? -time.m_data : time.m_data);
       
   740 }
       
   741 
       
   742 /**
       
   743  * \brief Time output streamer.
   768  * \brief Time output streamer.
   744  * 
   769  * 
   745  * Generates output such as "3.96ns".  Times are printed with the
   770  * Generates output such as "3.96ns".  Times are printed with the
   746  * following format flags (independent of the stream flags):
   771  * following format flags (independent of the stream flags):
   747  *   - `showpos`
   772  *   - `showpos`
   748  *   - `fixed`
   773  *   - `fixed`
   749  *   - `left`
   774  *   - `left`
   750  * The stream `width` and `precision` are ignored; Time output always
   775  * The stream `width` and `precision` are ignored; Time output always
   751  * includes ".0".
   776  * includes ".0".
   752  * \relates Time
   777  *
   753  */
   778  * \param [in] os The output stream.
   754 std::ostream & operator<< (std::ostream & os, const Time & time);
   779  * \param [in] time The Time to put on the stream.
   755 /**
   780  * \return The stream.
       
   781  */
       
   782 std::ostream & operator << (std::ostream & os, const Time & time);
       
   783 /**
       
   784  * \ingroup time
   756  * \brief Time input streamer
   785  * \brief Time input streamer
   757  *
   786  *
   758  * Uses the Time::Time (const std::string &) constructor
   787  * Uses the Time::Time (const std::string &) constructor
   759  * \relates Time
   788  *
   760  */
   789  * \param [in] is The input stream.
   761 std::istream & operator>> (std::istream & is, Time & time);
   790  * \param [out] time The Time variable to set from the stream data.
   762 
   791  * \return The stream.
   763 /**
   792  */
   764  * \brief create ns3::Time instances in units of seconds.
   793 std::istream & operator >> (std::istream & is, Time & time);
       
   794 
       
   795 /**
       
   796  * \ingroup time
       
   797  * \defgroup timecivil Standard time units.
       
   798  * \brief Convenience constructors in standard units.
   765  *
   799  *
   766  * For example:
   800  * For example:
   767  * \code
   801  * \code
   768  * Time t = Seconds (2.0);
   802  *   Time t = Seconds (2.0);
   769  * Simulator::Schedule (Seconds (5.0), ...);
   803  *   Simulator::Schedule (Seconds (5.0), ...);
   770  * \endcode
   804  * \endcode
   771  * \param seconds seconds value
   805  */
   772  * \relates Time
   806 /**
   773  */
   807  * \ingroup timecivil
   774 inline Time Seconds (double seconds)
   808  * Construct a Time in the indicated unit.
   775 {
   809  * \param value The value
   776   return Time::FromDouble (seconds, Time::S);
   810  * \return The Time
   777 }
   811  * @{
   778 
   812  */
   779 /**
   813 inline Time Years (double value)
   780  * \brief create ns3::Time instances in units of milliseconds.
   814 {
   781  *
   815   return Time::FromDouble (value, Time::Y);
   782  * For example:
   816 }
   783  * \code
   817 inline Time Years (int64x64_t value)
   784  * Time t = MilliSeconds (2);
   818 {
   785  * Simulator::Schedule (MilliSeconds (5), ...);
   819   return Time::From (value, Time::Y);
   786  * \endcode
   820 }
   787  * \param ms milliseconds value
   821 inline Time Days (double value)
   788  * \relates Time
   822 {
   789  */
   823   return Time::FromDouble (value, Time::D);
   790 inline Time MilliSeconds (uint64_t ms)
   824 }
   791 {
   825 inline Time Days (int64x64_t value)
   792   return Time::FromInteger (ms, Time::MS);
   826 {
   793 }
   827   return Time::From (value, Time::D);
   794 /**
   828 }
   795  * \brief create ns3::Time instances in units of microseconds.
   829 inline Time Hours (double value)
   796  *
   830 {
   797  * For example:
   831   return Time::FromDouble (value, Time::H);
   798  * \code
   832 }
   799  * Time t = MicroSeconds (2);
   833 inline Time Hours (int64x64_t value)
   800  * Simulator::Schedule (MicroSeconds (5), ...);
   834 {
   801  * \endcode
   835   return Time::From (value, Time::H);
   802  * \param us microseconds value
   836 }
   803  * \relates Time
   837 inline Time Minutes (double value)
   804  */
   838 {
   805 inline Time MicroSeconds (uint64_t us)
   839   return Time::FromDouble (value, Time::MIN);
   806 {
   840 }
   807   return Time::FromInteger (us, Time::US);
   841 inline Time Minutes (int64x64_t value)
   808 }
   842 {
   809 /**
   843   return Time::From (value, Time::MIN);
   810  * \brief create ns3::Time instances in units of nanoseconds.
   844 }
   811  *
   845 inline Time Seconds (double value)
   812  * For example:
   846 {
   813  * \code
   847   return Time::FromDouble (value, Time::S);
   814  * Time t = NanoSeconds (2);
   848 }
   815  * Simulator::Schedule (NanoSeconds (5), ...);
   849 inline Time Seconds (int64x64_t value)
   816  * \endcode
   850 {
   817  * \param ns nanoseconds value
   851   return Time::From (value, Time::S);
   818  * \relates Time
   852 }
   819  */
   853 inline Time MilliSeconds (uint64_t value)
   820 inline Time NanoSeconds (uint64_t ns)
   854 {
   821 {
   855   return Time::FromInteger (value, Time::MS);
   822   return Time::FromInteger (ns, Time::NS);
   856 }
   823 }
   857 inline Time MilliSeconds (int64x64_t value)
   824 /**
   858 {
   825  * \brief create ns3::Time instances in units of picoseconds.
   859   return Time::From (value, Time::MS);
   826  *
   860 }
   827  * For example:
   861 inline Time MicroSeconds (uint64_t value)
   828  * \code
   862 {
   829  * Time t = PicoSeconds (2);
   863   return Time::FromInteger (value, Time::US);
   830  * Simulator::Schedule (PicoSeconds (5), ...);
   864 }
   831  * \endcode
   865 inline Time MicroSeconds (int64x64_t value)
   832  * \param ps picoseconds value
   866 {
   833  * \relates Time
   867   return Time::From (value, Time::US);
   834  */
   868 }
   835 inline Time PicoSeconds (uint64_t ps)
   869 inline Time NanoSeconds (uint64_t value)
   836 {
   870 {
   837   return Time::FromInteger (ps, Time::PS);
   871   return Time::FromInteger (value, Time::NS);
   838 }
   872 }
   839 /**
   873 inline Time NanoSeconds (int64x64_t value)
   840  * \brief create ns3::Time instances in units of femtoseconds.
   874 {
   841  *
   875   return Time::From (value, Time::NS);
   842  * For example:
   876 }
   843  * \code
   877 inline Time PicoSeconds (uint64_t value)
   844  * Time t = FemtoSeconds (2);
   878 {
   845  * Simulator::Schedule (FemtoSeconds (5), ...);
   879   return Time::FromInteger (value, Time::PS);
   846  * \endcode
   880 }
   847  * \param fs femtoseconds value
   881 inline Time PicoSeconds (int64x64_t value)
   848  * \relates Time
   882 {
   849  */
   883   return Time::From (value, Time::PS);
   850 inline Time FemtoSeconds (uint64_t fs)
   884 }
   851 {
   885 inline Time FemtoSeconds (uint64_t value)
   852   return Time::FromInteger (fs, Time::FS);
   886 {
   853 }
   887   return Time::FromInteger (value, Time::FS);
   854 /**
   888 }
   855  * \brief create ns3::Time instances in units of minutes (equal to 60 seconds).
   889 inline Time FemtoSeconds (int64x64_t value)
   856  *
   890 {
   857  * For example:
   891   return Time::From (value, Time::FS);
   858  * \code
   892 }
   859  * Time t = Minutes (2.0);
   893 /**@}*/
   860  * Simulator::Schedule (Minutes (5.0), ...);
   894   
   861  * \endcode
   895 
   862  * \param minutes mintues value
   896 /**
   863  * \relates Time
   897  *  \ingroup time
   864  */
   898  *  \internal Scheduler interface
   865 inline Time Minutes (double minutes)
   899  *  \param [in] ts The time value, in the current unit.
   866 {
   900  *  \return A Time.
   867   return Time::FromDouble (minutes, Time::MIN);
   901  */
   868 }
       
   869 /**
       
   870  * \brief create ns3::Time instances in units of hours (equal to 60 minutes).
       
   871  *
       
   872  * For example:
       
   873  * \code
       
   874  * Time t = Hours (2.0);
       
   875  * Simulator::Schedule (Hours (5.0), ...);
       
   876  * \endcode
       
   877  * \param hours hours value
       
   878  * \relates Time
       
   879  */
       
   880 inline Time Hours (double hours)
       
   881 {
       
   882   return Time::FromDouble (hours, Time::H);
       
   883 }
       
   884 /**
       
   885  * \brief create ns3::Time instances in units of days (equal to 24 hours).
       
   886  *
       
   887  * For example:
       
   888  * \code
       
   889  * Time t = Days (2.0);
       
   890  * Simulator::Schedule (Days (5.0), ...);
       
   891  * \endcode
       
   892  * \param days days value
       
   893  * \relates Time
       
   894  */
       
   895 inline Time Days (double days)
       
   896 {
       
   897   return Time::FromDouble (days, Time::D);
       
   898 }
       
   899 /**
       
   900  * \brief create ns3::Time instances in units of years (equal to 365 days).
       
   901  *
       
   902  * For example:
       
   903  * \code
       
   904  * Time t = Years (2.0);
       
   905  * Simulator::Schedule (Years (5.0), ...);
       
   906  * \endcode
       
   907  * \param years years value
       
   908  * \relates Time
       
   909  */
       
   910 inline Time Years (double years)
       
   911 {
       
   912   return Time::FromDouble (years, Time::Y);
       
   913 }
       
   914 
       
   915 /**
       
   916  * \see Seconds(double)
       
   917  * \relates Time
       
   918  */
       
   919 inline Time Seconds (int64x64_t seconds)
       
   920 {
       
   921   return Time::From (seconds, Time::S);
       
   922 }
       
   923 /**
       
   924  * \see MilliSeconds(uint64_t)
       
   925  * \relates Time
       
   926  */
       
   927 inline Time MilliSeconds (int64x64_t ms)
       
   928 {
       
   929   return Time::From (ms, Time::MS);
       
   930 }
       
   931 /**
       
   932  * \see MicroSeconds(uint64_t)
       
   933  * \relates Time
       
   934  */
       
   935 inline Time MicroSeconds (int64x64_t us)
       
   936 {
       
   937   return Time::From (us, Time::US);
       
   938 }
       
   939 /**
       
   940  * \see NanoSeconds(uint64_t)
       
   941  * \relates Time
       
   942  */
       
   943 inline Time NanoSeconds (int64x64_t ns)
       
   944 {
       
   945   return Time::From (ns, Time::NS);
       
   946 }
       
   947 /**
       
   948  * \see PicoSeconds(uint64_t)
       
   949  * \relates Time
       
   950  */
       
   951 inline Time PicoSeconds (int64x64_t ps)
       
   952 {
       
   953   return Time::From (ps, Time::PS);
       
   954 }
       
   955 /**
       
   956  * \see FemtoSeconds(uint64_t)
       
   957  * \relates Time
       
   958  */
       
   959 inline Time FemtoSeconds (int64x64_t fs)
       
   960 {
       
   961   return Time::From (fs, Time::FS);
       
   962 }
       
   963 /**
       
   964  * \see Minutes(uint64_t)
       
   965  * \relates Time
       
   966  */
       
   967 inline Time Minutes (int64x64_t minutes)
       
   968 {
       
   969   return Time::From (minutes, Time::MIN);
       
   970 }
       
   971 /**
       
   972  * \see Minutes(uint64_t)
       
   973  * \relates Time
       
   974  */
       
   975 inline Time Hours (int64x64_t hours)
       
   976 {
       
   977   return Time::From (hours, Time::H);
       
   978 }
       
   979 /**
       
   980  * \see Minutes(uint64_t)
       
   981  * \relates Time
       
   982  */
       
   983 inline Time Days (int64x64_t days)
       
   984 {
       
   985   return Time::From (days, Time::D);
       
   986 }
       
   987 /**
       
   988  * \see Minutes(uint64_t)
       
   989  * \relates Time
       
   990  */
       
   991 inline Time Years (int64x64_t years)
       
   992 {
       
   993   return Time::From (years, Time::Y);
       
   994 }
       
   995 
       
   996 // internal function not publicly documented
       
   997 inline Time TimeStep (uint64_t ts)
   902 inline Time TimeStep (uint64_t ts)
   998 {
   903 {
   999   return Time (ts);
   904   return Time (ts);
  1000 }
   905 }
  1001 
   906 
  1002 /**
   907 /**
       
   908  * \ingroup time
  1003  * \class ns3::TimeValue
   909  * \class ns3::TimeValue
  1004  * \brief hold objects of type ns3::Time
   910  * \brief Attribute for objects of type ns3::Time
  1005  */
   911  */
  1006 
       
  1007 
       
  1008 ATTRIBUTE_VALUE_DEFINE (Time);
   912 ATTRIBUTE_VALUE_DEFINE (Time);
       
   913 
       
   914 /**
       
   915  *  Attribute accessor function for Time
       
   916  *  @{
       
   917  */
  1009 ATTRIBUTE_ACCESSOR_DEFINE (Time);
   918 ATTRIBUTE_ACCESSOR_DEFINE (Time);
  1010 
   919 /**@}*/
  1011 /**
   920 
  1012  * \brief Helper to make a Time checker with bounded range.
   921 /**
  1013  * Both limits are inclusive
   922  *  \ingroup time
  1014  *
   923  *  \brief Helper to make a Time checker with bounded range.
  1015  * \return the AttributeChecker
   924  *  Both limits are inclusive
       
   925  *
       
   926  *  \param [in] min Minimum allowed value.
       
   927  *  \param [in] max Maximum allowed value.
       
   928  *  \return the AttributeChecker
  1016  */
   929  */
  1017 Ptr<const AttributeChecker> MakeTimeChecker (const Time min, const Time max);
   930 Ptr<const AttributeChecker> MakeTimeChecker (const Time min, const Time max);
  1018 
   931 
  1019 /**
   932 /**
       
   933  * \ingroup time
  1020  * \brief Helper to make an unbounded Time checker.
   934  * \brief Helper to make an unbounded Time checker.
  1021  *
   935  *
  1022  * \return the AttributeChecker
   936  * \return the AttributeChecker
  1023  */
   937  */
  1024 inline
   938 inline
  1026 {
   940 {
  1027   return MakeTimeChecker (Time::Min (), Time::Max ());
   941   return MakeTimeChecker (Time::Min (), Time::Max ());
  1028 }
   942 }
  1029 
   943 
  1030 /**
   944 /**
       
   945  * \ingroup time
  1031  * \brief Helper to make a Time checker with a lower bound.
   946  * \brief Helper to make a Time checker with a lower bound.
  1032  *
   947  *
       
   948  *  \param [in] min Minimum allowed value.
  1033  * \return the AttributeChecker
   949  * \return the AttributeChecker
  1034  */
   950  */
  1035 inline
   951 inline
  1036 Ptr<const AttributeChecker> MakeTimeChecker (const Time min)
   952 Ptr<const AttributeChecker> MakeTimeChecker (const Time min)
  1037 {
   953 {
  1058 
   974 
  1059 private:
   975 private:
  1060   Time m_time;        //!< The time
   976   Time m_time;        //!< The time
  1061   Time::Unit m_unit;  //!< The unit to use in output
   977   Time::Unit m_unit;  //!< The unit to use in output
  1062 
   978 
  1063   /// Output streamer
   979   /**
  1064   friend std::ostream & operator << (std::ostream & os, const TimeWithUnit & time);
   980    *  Output streamer
       
   981    *  \param [in] os The stream.
       
   982    *  \param [in] timeU The Time with desired unit
       
   983    *  \returns The stream.
       
   984    */
       
   985   friend std::ostream & operator << (std::ostream & os, const TimeWithUnit & timeU);
  1065 
   986 
  1066 };  // class TimeWithUnit
   987 };  // class TimeWithUnit
  1067 
   988 
  1068 } // namespace ns3
   989 } // namespace ns3
  1069 
   990