src/simulator/nstime.h
changeset 6496 ed210e7279a7
parent 6411 04827770e83d
child 6514 92a84235d8f2
equal deleted inserted replaced
6495:cacb64774b1a 6496:ed210e7279a7
    25 #include "ns3/attribute-helper.h"
    25 #include "ns3/attribute-helper.h"
    26 #include <stdint.h>
    26 #include <stdint.h>
    27 #include <math.h>
    27 #include <math.h>
    28 #include <ostream>
    28 #include <ostream>
    29 #include "high-precision.h"
    29 #include "high-precision.h"
       
    30 #include "time-base.h"
    30 
    31 
    31 namespace ns3 {
    32 namespace ns3 {
    32 
       
    33 namespace TimeStepPrecision {
       
    34 
       
    35 enum precision_t
       
    36 {
       
    37   S  = 0,
       
    38   MS = 3,
       
    39   US = 6,
       
    40   NS = 9,
       
    41   PS = 12,
       
    42   FS = 15
       
    43 };
       
    44 /**
       
    45  * \param precision the new precision to use
       
    46  *
       
    47  * This should be invoked before any Time object
       
    48  * is created. i.e., it should be invoked at the very start
       
    49  * of every simulation. The unit specified by this method
       
    50  * is used as the unit of the internal simulation time
       
    51  * which is stored as a 64 bit integer.
       
    52  */
       
    53 void Set (precision_t precision);
       
    54 /**
       
    55  * \returns the currently-used time precision.
       
    56  */
       
    57 precision_t Get (void);
       
    58 
       
    59 } // namespace TimeStepPrecision
       
    60 
    33 
    61 
    34 
    62 /**
    35 /**
    63  * \ingroup simulator
    36  * \ingroup simulator
    64  * \defgroup time Time
    37  * \defgroup time Time
   108  *  - \ref ns3-Time-Abs ns3::Abs
    81  *  - \ref ns3-Time-Abs ns3::Abs
   109  *  - \ref ns3-Time-Max ns3::Max
    82  *  - \ref ns3-Time-Max ns3::Max
   110  *  - \ref ns3-Time-Min ns3::Min
    83  *  - \ref ns3-Time-Min ns3::Min
   111  */
    84  */
   112 template <int N>
    85 template <int N>
   113 class TimeUnit
    86 class TimeUnit : public TimeBase
   114 {
    87 {
   115 public:
    88 public:
   116   TimeUnit ();
    89   explicit inline TimeUnit (const HighPrecision &data)
   117   TimeUnit (TimeUnit const &o);
    90     : TimeBase (data)
   118   TimeUnit operator = (TimeUnit const &o);
    91   {}
   119   TimeUnit (HighPrecision data);
       
   120 
       
   121   /**
       
   122    * \return true if the time is zero, false otherwise.
       
   123    */
       
   124   bool IsZero (void) const;
       
   125   /**
       
   126    * \return true if the time is negative or zero, false otherwise.
       
   127    */
       
   128   bool IsNegative (void) const;
       
   129   /**
       
   130    * \return true if the time is positive or zero, false otherwise.
       
   131    */
       
   132   bool IsPositive (void) const;
       
   133   /**
       
   134    * \return true if the time is strictly negative, false otherwise.
       
   135    */
       
   136   bool IsStrictlyNegative (void) const;
       
   137   /**
       
   138    * \return true if the time is strictly positive, false otherwise.
       
   139    */
       
   140   bool IsStrictlyPositive (void) const;
       
   141 
       
   142   /**
       
   143    * This is really an internal method exported for the needs of
       
   144    * the implementation. Please, Do not try to use this method, ever.
       
   145    *
       
   146    * \return the ns3::HighPrecision object which holds the value
       
   147    *         stored in this Time<N> type.
       
   148    */
       
   149   HighPrecision const &GetHighPrecision (void) const;
       
   150   HighPrecision * PeekHighPrecision (void);
       
   151 
       
   152 private:
       
   153   HighPrecision m_data;
       
   154 };
    92 };
   155 
       
   156 template <int N>
       
   157 TimeUnit<N>::TimeUnit ()
       
   158   : m_data ()
       
   159 {
       
   160 }
       
   161 template <int N>
       
   162 TimeUnit<N>::TimeUnit (TimeUnit const &o)
       
   163   : m_data (o.m_data)
       
   164 {
       
   165 }
       
   166 template <int N>
       
   167 TimeUnit<N>
       
   168 TimeUnit<N>::operator = (TimeUnit const &o)
       
   169 {
       
   170   m_data = o.m_data;
       
   171   return *this;
       
   172 }
       
   173 template <int N>
       
   174 TimeUnit<N>::TimeUnit (HighPrecision data)
       
   175   : m_data (data)
       
   176 {
       
   177 }
       
   178 
       
   179 template <int N>
       
   180 HighPrecision const &
       
   181 TimeUnit<N>::GetHighPrecision (void) const
       
   182 {
       
   183   return m_data;
       
   184 }
       
   185 template <int N>
       
   186 HighPrecision *
       
   187 TimeUnit<N>::PeekHighPrecision (void)
       
   188 {
       
   189   return &m_data;
       
   190 }
       
   191 template <int N>
       
   192 bool
       
   193 TimeUnit<N>::IsZero (void) const
       
   194 {
       
   195   return m_data.Compare (HighPrecision::Zero ()) == 0;
       
   196 }
       
   197 template <int N>
       
   198 bool
       
   199 TimeUnit<N>::IsNegative (void) const
       
   200 {
       
   201   return m_data.Compare (HighPrecision::Zero ()) <= 0;
       
   202 }
       
   203 template <int N>
       
   204 bool
       
   205 TimeUnit<N>::IsPositive (void) const
       
   206 {
       
   207   return m_data.Compare (HighPrecision::Zero ()) >= 0;
       
   208 }
       
   209 template <int N>
       
   210 bool
       
   211 TimeUnit<N>::IsStrictlyNegative (void) const
       
   212 {
       
   213   return m_data.Compare (HighPrecision::Zero ()) < 0;
       
   214 }
       
   215 template <int N>
       
   216 bool
       
   217 TimeUnit<N>::IsStrictlyPositive (void) const
       
   218 {
       
   219   return m_data.Compare (HighPrecision::Zero ()) > 0;
       
   220 }
       
   221 
    93 
   222 template <int N>
    94 template <int N>
   223 bool
    95 bool
   224 operator == (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
    96 operator == (TimeUnit<N> const &lhs, TimeUnit<N> const &rhs)
   225 {
    97 {
   345 // \class TimeUnit<1>
   217 // \class TimeUnit<1>
   346 
   218 
   347 class TimeValue;
   219 class TimeValue;
   348 
   220 
   349 template <>
   221 template <>
   350 class TimeUnit<1>
   222 class TimeUnit<1> : public TimeBase
   351 {
   223 {
   352   // -*- New methods -*-
   224   // -*- New methods -*-
   353 public:
   225 public:
   354   /**
   226   /**
   355    * \brief String constructor
   227    * \brief String constructor
   366    * and the units.  Any otherwise malformed string causes a fatal error to
   238    * and the units.  Any otherwise malformed string causes a fatal error to
   367    * occur.
   239    * occur.
   368    * \param s The string to parse into a TimeUnit<1>
   240    * \param s The string to parse into a TimeUnit<1>
   369    */
   241    */
   370   TimeUnit<1> (const std::string & s);
   242   TimeUnit<1> (const std::string & s);
       
   243 
   371   /**
   244   /**
   372    * \returns an approximation in seconds of the time stored in this
   245    * \returns an approximation in seconds of the time stored in this
   373    *          instance.
   246    *          instance.
   374    */
   247    */
   375   double GetSeconds (void) const;
   248   inline double GetSeconds (void) const
       
   249   {
       
   250     return TimeBase::ToDouble (*this, TimeBase::S);
       
   251   }
   376 
   252 
   377   /**
   253   /**
   378    * \returns an approximation in milliseconds of the time stored in this
   254    * \returns an approximation in milliseconds of the time stored in this
   379    *          instance.
   255    *          instance.
   380    */
   256    */
   381   int64_t GetMilliSeconds (void) const;
   257   inline int64_t GetMilliSeconds (void) const
       
   258   {
       
   259     return TimeBase::ToInteger (*this, TimeBase::MS);
       
   260   }
   382   /**
   261   /**
   383    * \returns an approximation in microseconds of the time stored in this
   262    * \returns an approximation in microseconds of the time stored in this
   384    *          instance.
   263    *          instance.
   385    */
   264    */
   386   int64_t GetMicroSeconds (void) const;
   265   inline int64_t GetMicroSeconds (void) const
       
   266   {
       
   267     return TimeBase::ToInteger (*this, TimeBase::US);
       
   268   }
   387   /**
   269   /**
   388    * \returns an approximation in nanoseconds of the time stored in this
   270    * \returns an approximation in nanoseconds of the time stored in this
   389    *          instance.
   271    *          instance.
   390    */
   272    */
   391   int64_t GetNanoSeconds (void) const;
   273   inline int64_t GetNanoSeconds (void) const
       
   274   {
       
   275     return TimeBase::ToInteger (*this, TimeBase::NS);
       
   276   }
   392   /**
   277   /**
   393    * \returns an approximation in picoseconds of the time stored in this
   278    * \returns an approximation in picoseconds of the time stored in this
   394    *          instance.
   279    *          instance.
   395    */
   280    */
   396   int64_t GetPicoSeconds (void) const;
   281   inline int64_t GetPicoSeconds (void) const
       
   282   {
       
   283     return TimeBase::ToInteger (*this, TimeBase::PS);
       
   284   }
   397   /**
   285   /**
   398    * \returns an approximation in femtoseconds of the time stored in this
   286    * \returns an approximation in femtoseconds of the time stored in this
   399    *          instance.
   287    *          instance.
   400    */
   288    */
   401   int64_t GetFemtoSeconds (void) const;
   289   inline int64_t GetFemtoSeconds (void) const
       
   290   {
       
   291     return TimeBase::ToInteger (*this, TimeBase::FS);
       
   292   }
   402   /**
   293   /**
   403    * \returns an approximation of the time stored in this
   294    * \returns an approximation of the time stored in this
   404    *          instance in the units specified in m_tsPrecision.
   295    *          instance in the units specified in m_tsPrecision.
   405    */
   296    */
   406   int64_t GetTimeStep (void) const;
   297   inline int64_t GetTimeStep (void) const
   407 
   298   {
   408   // -*- The rest is the the same as in the generic template class -*-
   299     int64_t timeValue = GetHighPrecision ().GetInteger ();
   409 public:
   300     return timeValue;
   410   TimeUnit ()
   301   }
   411     : m_data ()
   302   inline TimeUnit ()
   412   {
   303     : TimeBase () {}
   413   }
   304   inline TimeUnit (const TimeBase &o)
   414   TimeUnit (TimeUnit const &o)
   305     : TimeBase (o) {}
   415     : m_data (o.m_data)
   306   explicit inline TimeUnit<1> (const HighPrecision &o)
   416   {
   307     : TimeBase (o) {}
   417   }
       
   418   TimeUnit operator = (TimeUnit const &o)
       
   419   {
       
   420     m_data = o.m_data;
       
   421     return *this;
       
   422   }
       
   423   TimeUnit (HighPrecision data)
       
   424     : m_data (data)
       
   425   {
       
   426   }
       
   427   bool IsZero (void) const
       
   428   {
       
   429     return m_data.Compare (HighPrecision::Zero ()) == 0;
       
   430   }
       
   431   bool IsNegative (void) const
       
   432   {
       
   433     return m_data.Compare (HighPrecision::Zero ()) <= 0;
       
   434   }
       
   435   bool IsPositive (void) const
       
   436   {
       
   437     return m_data.Compare (HighPrecision::Zero ()) >= 0;
       
   438   }
       
   439   bool IsStrictlyNegative (void) const
       
   440   {
       
   441     return m_data.Compare (HighPrecision::Zero ()) < 0;
       
   442   }
       
   443   bool IsStrictlyPositive (void) const
       
   444   {
       
   445     return m_data.Compare (HighPrecision::Zero ()) > 0;
       
   446   }
       
   447   HighPrecision const &GetHighPrecision (void) const
       
   448   {
       
   449     return m_data;
       
   450   }
       
   451   HighPrecision * PeekHighPrecision (void)
       
   452   {
       
   453     return &m_data;
       
   454   }
       
   455 
       
   456   static uint64_t UnitsToTimestep (uint64_t unitValue,
       
   457                                    uint64_t unitFactor);
       
   458 
       
   459 private:
       
   460   HighPrecision m_data;
       
   461 
       
   462   /*
       
   463    * \Returns the value of time_value in units of unitPrec. time_value
       
   464    * must be specified in timestep units (which are the same as the
       
   465    * m_tsPrecision units
       
   466    */
       
   467   int64_t ConvertToUnits (int64_t timeValue, uint64_t unitFactor) const;
       
   468 };
   308 };
   469 
   309 
   470 /**
   310 /**
   471  * \brief keep track of seconds.
   311  * \brief keep track of seconds.
   472  *
   312  *
   549  * Time t = Seconds (2.0);
   389  * Time t = Seconds (2.0);
   550  * Simulator::Schedule (NanoSeconds (5.0), ...);
   390  * Simulator::Schedule (NanoSeconds (5.0), ...);
   551  * \endcode
   391  * \endcode
   552  * \param seconds seconds value
   392  * \param seconds seconds value
   553  */
   393  */
   554 Time Seconds (double seconds);
   394 inline Time Seconds (double seconds)
       
   395 {
       
   396   return TimeBase::FromDouble (seconds, TimeBase::S);
       
   397 }
   555 
   398 
   556 /**
   399 /**
   557  * \brief create ns3::Time instances in units of milliseconds.
   400  * \brief create ns3::Time instances in units of milliseconds.
   558  *
   401  *
   559  * For example:
   402  * For example:
   561  * Time t = MilliSeconds (2);
   404  * Time t = MilliSeconds (2);
   562  * Simulator::Schedule (MilliSeconds (5), ...);
   405  * Simulator::Schedule (MilliSeconds (5), ...);
   563  * \endcode
   406  * \endcode
   564  * \param ms milliseconds value
   407  * \param ms milliseconds value
   565  */
   408  */
   566 Time MilliSeconds (uint64_t ms);
   409 inline Time MilliSeconds (uint64_t ms)
       
   410 {
       
   411   return TimeBase::FromInteger (ms, TimeBase::MS);
       
   412 }
   567 /**
   413 /**
   568  * \brief create ns3::Time instances in units of microseconds.
   414  * \brief create ns3::Time instances in units of microseconds.
   569  *
   415  *
   570  * For example:
   416  * For example:
   571  * \code
   417  * \code
   572  * Time t = MicroSeconds (2);
   418  * Time t = MicroSeconds (2);
   573  * Simulator::Schedule (MicroSeconds (5), ...);
   419  * Simulator::Schedule (MicroSeconds (5), ...);
   574  * \endcode
   420  * \endcode
   575  * \param us microseconds value
   421  * \param us microseconds value
   576  */
   422  */
   577 Time MicroSeconds (uint64_t us);
   423 inline Time MicroSeconds (uint64_t us)
       
   424 {
       
   425   return TimeBase::FromInteger (us, TimeBase::US);
       
   426 }
   578 /**
   427 /**
   579  * \brief create ns3::Time instances in units of nanoseconds.
   428  * \brief create ns3::Time instances in units of nanoseconds.
   580  *
   429  *
   581  * For example:
   430  * For example:
   582  * \code
   431  * \code
   583  * Time t = NanoSeconds (2);
   432  * Time t = NanoSeconds (2);
   584  * Simulator::Schedule (NanoSeconds (5), ...);
   433  * Simulator::Schedule (NanoSeconds (5), ...);
   585  * \endcode
   434  * \endcode
   586  * \param ns nanoseconds value
   435  * \param ns nanoseconds value
   587  */
   436  */
   588 Time NanoSeconds (uint64_t ns);
   437 inline Time NanoSeconds (uint64_t ns)
       
   438 {
       
   439   return TimeBase::FromInteger (ns, TimeBase::NS);
       
   440 }
   589 /**
   441 /**
   590  * \brief create ns3::Time instances in units of picoseconds.
   442  * \brief create ns3::Time instances in units of picoseconds.
   591  *
   443  *
   592  * For example:
   444  * For example:
   593  * \code
   445  * \code
   594  * Time t = PicoSeconds (2);
   446  * Time t = PicoSeconds (2);
   595  * Simulator::Schedule (PicoSeconds (5), ...);
   447  * Simulator::Schedule (PicoSeconds (5), ...);
   596  * \endcode
   448  * \endcode
   597  * \param ps picoseconds value
   449  * \param ps picoseconds value
   598  */
   450  */
   599 Time PicoSeconds (uint64_t ps);
   451 inline Time PicoSeconds (uint64_t ps)
       
   452 {
       
   453   return TimeBase::FromInteger (ps, TimeBase::PS);
       
   454 }
   600 /**
   455 /**
   601  * \brief create ns3::Time instances in units of femtoseconds.
   456  * \brief create ns3::Time instances in units of femtoseconds.
   602  *
   457  *
   603  * For example:
   458  * For example:
   604  * \code
   459  * \code
   605  * Time t = FemtoSeconds (2);
   460  * Time t = FemtoSeconds (2);
   606  * Simulator::Schedule (FemtoSeconds (5), ...);
   461  * Simulator::Schedule (FemtoSeconds (5), ...);
   607  * \endcode
   462  * \endcode
   608  * \param fs femtoseconds value
   463  * \param fs femtoseconds value
   609  */
   464  */
   610 Time FemtoSeconds (uint64_t fs);
   465 inline Time FemtoSeconds (uint64_t fs)
       
   466 {
       
   467   return TimeBase::FromInteger (fs, TimeBase::FS);
       
   468 }
   611 
   469 
   612 // internal function not publicly documented
   470 // internal function not publicly documented
   613 Time TimeStep (uint64_t ts);
   471 inline Time TimeStep (uint64_t ts)
       
   472 {
       
   473   return Time (HighPrecision (ts, false));
       
   474 }
   614 
   475 
   615 // Explicit instantiation of the TimeUnit template for N=0, with a few
   476 // Explicit instantiation of the TimeUnit template for N=0, with a few
   616 // additional methods that should not be available for N != 0
   477 // additional methods that should not be available for N != 0
   617 template <>
   478 template <>
   618 class TimeUnit<0>
   479 class TimeUnit<0> : public TimeBase
   619 {
   480 {
   620   // -*- New methods -*-
   481   // -*- New methods -*-
   621 public:
   482 public:
   622   double GetDouble (void) const;
   483   double GetDouble (void) const;
   623   TimeUnit<0> (double scalar);
   484   TimeUnit<0> (double scalar);
   624 
   485   TimeUnit<0> ();
   625   // -*- The rest is the the same as in the generic template class -*-
   486   TimeUnit<0> (const TimeUnit &o);
   626 public:
   487   explicit TimeUnit<0> (const HighPrecision &o);
   627   TimeUnit ()
       
   628     : m_data ()
       
   629   {
       
   630   }
       
   631   TimeUnit (TimeUnit const &o)
       
   632     : m_data (o.m_data)
       
   633   {
       
   634   }
       
   635   TimeUnit operator = (TimeUnit const &o)
       
   636   {
       
   637     m_data = o.m_data;
       
   638     return *this;
       
   639   }
       
   640   TimeUnit (HighPrecision data)
       
   641     : m_data (data)
       
   642   {
       
   643   }
       
   644   bool IsZero (void) const
       
   645   {
       
   646     return m_data.Compare (HighPrecision::Zero ()) == 0;
       
   647   }
       
   648   bool IsNegative (void) const
       
   649   {
       
   650     return m_data.Compare (HighPrecision::Zero ()) <= 0;
       
   651   }
       
   652   bool IsPositive (void) const
       
   653   {
       
   654     return m_data.Compare (HighPrecision::Zero ()) >= 0;
       
   655   }
       
   656   bool IsStrictlyNegative (void) const
       
   657   {
       
   658     return m_data.Compare (HighPrecision::Zero ()) < 0;
       
   659   }
       
   660   bool IsStrictlyPositive (void) const
       
   661   {
       
   662     return m_data.Compare (HighPrecision::Zero ()) > 0;
       
   663   }
       
   664   HighPrecision const &GetHighPrecision (void) const
       
   665   {
       
   666     return m_data;
       
   667   }
       
   668   HighPrecision * PeekHighPrecision (void)
       
   669   {
       
   670     return &m_data;
       
   671   }
       
   672 
       
   673 private:
       
   674   HighPrecision m_data;
       
   675 };
   488 };
   676 
   489 
   677 /**
   490 /**
   678  * \brief hold scalar values
   491  * \brief hold scalar values
   679  *
   492  *