Simplify output of Times in a specific unit; see Time::As ()

This commit is contained in:
Peter D. Barnes, Jr.
2014-04-02 18:47:04 -07:00
parent 210aefc777
commit 45530120f2
4 changed files with 162 additions and 49 deletions

View File

@@ -22,6 +22,7 @@ Supported platforms
New user-visible features
-------------------------
- Simplify output of Times in a specific unit; see Time::As ()
- Enable selection of high precision int64x64_t implementation
at configure time, for debugging purposes.
- A new LTE MAC downlink scheduling algorithm named Channel and QoS

View File

@@ -33,6 +33,8 @@
namespace ns3 {
class TimeWithUnit;
/**
* \ingroup core
* \brief Simulation virtual time values and global simulation resolution.
@@ -488,6 +490,20 @@ public:
return Time (value);
}
/**
* Attach a unit to a Time, to facilitate output in a specific unit.
*
* For example,
* \code
* Time t (3.14e9); // Pi seconds
* std::cout << t.As (Time::MS) << std::endl;
* \code
* will print ``+3140.0ms``
*
* \param unit [in] The unit to use.
*/
TimeWithUnit As (const enum Unit unit) const;
private:
/**
* How to convert between other units and the current unit
@@ -1022,6 +1038,32 @@ Ptr<const AttributeChecker> MakeTimeChecker (const Time min)
return MakeTimeChecker (min, Time::Max ());
}
/**
* \ingroup time
* \brief A Time with attached unit, to facilitate output in that unit.
*/
class TimeWithUnit
{
public:
/**
* Attach a unit to a Time
*
* \param [in] time The time.
* \param [in] unit The unit to use for output
*/
TimeWithUnit (const Time time, const Time::Unit unit)
: m_time (time),
m_unit (unit)
{ };
private:
Time m_time; //!< The time
Time::Unit m_unit; //!< The unit to use in output
/// Output streamer
friend std::ostream & operator << (std::ostream & os, const TimeWithUnit & time);
}; // class TimeWithUnit
} // namespace ns3

View File

@@ -380,67 +380,53 @@ Time::GetResolution (void)
}
TimeWithUnit
Time::As (const enum Unit unit) const
{
return TimeWithUnit (*this, unit);
}
std::ostream&
operator<< (std::ostream& os, const Time & time)
{
os << time.As (Time::GetResolution ());
return os;
}
std::ostream &
operator << (std::ostream & os, const TimeWithUnit & timeU)
{
std::string unit;
Time::Unit res = Time::GetResolution ();
switch (res)
switch (timeU.m_unit)
{
case Time::S:
unit = "s";
break;
case Time::MS:
unit = "ms";
break;
case Time::US:
unit = "us";
break;
case Time::NS:
unit = "ns";
break;
case Time::PS:
unit = "ps";
break;
case Time::FS:
unit = "fs";
break;
case Time::MIN:
unit = "min";
break;
case Time::H:
unit = "h";
break;
case Time::D:
unit = "d";
break;
case Time::Y:
unit = "y";
break;
case Time::Y: unit = "y"; break;
case Time::D: unit = "d"; break;
case Time::H: unit = "h"; break;
case Time::MIN: unit = "min"; break;
case Time::S: unit = "s"; break;
case Time::MS: unit = "ms"; break;
case Time::US: unit = "us"; break;
case Time::NS: unit = "ns"; break;
case Time::PS: unit = "ps"; break;
case Time::FS: unit = "fs"; break;
case Time::LAST:
default:
NS_ABORT_MSG ("can't be reached");
unit = "unreachable";
break;
}
int64_t v = time.ToInteger (res);
std::ios_base::fmtflags ff = os.flags ();
os << std::setw (0) << std::left;
{ // See bug 1737: gcc libstc++ 4.2 bug
if (v == 0)
{
os << '+';
}
else
{
os << std::showpos;
}
}
os << v << ".0" << unit;
os.flags (ff); // Restore stream flags
int64x64_t v = timeU.m_time.To (timeU.m_unit);
os << v << unit;
return os;
}
std::istream& operator>> (std::istream& is, Time & time)
{
std::string value;

View File

@@ -19,7 +19,14 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* TimeStep support by Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
#include "ns3/nstime.h"
#include "ns3/int64x64.h"
#include "ns3/test.h"
using namespace ns3;
@@ -150,13 +157,90 @@ TimesWithSignsTestCase::DoTeardown (void)
{
}
class TimeIntputOutputTestCase : public TestCase
{
public:
TimeIntputOutputTestCase ();
private:
virtual void DoRun (void);
void Check (const std::string & str);
};
TimeIntputOutputTestCase::TimeIntputOutputTestCase ()
: TestCase ("Input,output from,to strings")
{
}
void
TimeIntputOutputTestCase::Check (const std::string & str)
{
std::stringstream ss (str);
Time time;
ss >> time;
ss << time;
bool pass = (str == ss.str ());
std::cout << GetParent ()->GetName () << " InputOutput: "
<< (pass ? "pass " : "FAIL ")
<< "\"" << str << "\"";
if (!pass)
{
std::cout << ", got " << ss.str ();
}
std::cout << std::endl;
}
void
TimeIntputOutputTestCase::DoRun (void)
{
std::cout << std::endl;
std::cout << GetParent ()->GetName () << " InputOutput: " << GetName ()
<< std::endl;
Check ("2ns");
Check ("+3.1us");
Check ("-4.2ms");
Check ("5.3s");
Check ("6.4min");
Check ("7.5h");
Check ("8.6d");
Check ("10.8y");
Time t (3.141592654e9); // Pi seconds
std::cout << GetParent ()->GetName () << " InputOutput: "
<< "example: raw: " << t
<< std::endl;
std::cout << GetParent ()->GetName () << " InputOutput: "
<< std::fixed << std::setprecision (9)
<< "example: in s: " << t.As (Time::S)
<< std::endl;
std::cout << GetParent ()->GetName () << " InputOutput: "
<< std::setprecision (6)
<< "example: in ms: " << t.As (Time::MS)
<< std::endl;
std::cout << GetParent ()->GetName () << " InputOutput: "
<< "example: Get ns: " << t.GetNanoSeconds ()
<< std::endl;
std::cout << std::endl;
}
static class TimeTestSuite : public TestSuite
{
public:
TimeTestSuite ()
: TestSuite ("time", UNIT)
{
AddTestCase (new TimeSimpleTestCase (), TestCase::QUICK);
AddTestCase (new TimesWithSignsTestCase (), TestCase::QUICK);
AddTestCase (new TimeIntputOutputTestCase (), TestCase::QUICK);
// This should be last, since it changes the resolution
AddTestCase (new TimeSimpleTestCase (), TestCase::QUICK);
}
} g_timeTestSuite;