#include <string>
#include <vector>
+#include "base/cast.hh"
+#include "base/cprintf.hh"
+#include "base/intmath.hh"
#include "base/stats/group.hh"
#include "base/stats/info.hh"
#include "base/stats/output.hh"
#include "base/stats/storage.hh"
#include "base/stats/types.hh"
-#include "base/cast.hh"
-#include "base/cprintf.hh"
-#include "base/intmath.hh"
+#include "base/stats/units.hh"
#include "base/str.hh"
#include "base/types.hh"
DataWrap(const DataWrap &) = delete;
DataWrap &operator=(const DataWrap &) = delete;
-
- DataWrap(Group *parent, const char *name, const char *desc)
+ DataWrap(Group *parent, const char *name, const Units::Base *unit,
+ const char *desc)
{
auto info = new Info(self());
this->setInfo(parent, info);
info->flags.set(display);
}
+ info->unit = unit;
+
if (desc)
info->desc = desc;
}
return this->info()->separatorString;
}
+ /**
+ * Set the unit of the stat.
+ * @param unit The new unit.
+ * @return A reference to this stat.
+ */
+ Derived &
+ unit(const Units::Base *_unit)
+ {
+ this->info()->unit = _unit;
+ return this->self();
+ }
+
/**
* Set the description and marks this stat to print at the end of
* simulation.
typedef InfoProxyType<Derived> Info;
DataWrapVec(Group *parent = nullptr, const char *name = nullptr,
+ const Units::Base *unit = UNIT_UNSPECIFIED,
const char *desc = nullptr)
- : DataWrap<Derived, InfoProxyType>(parent, name, desc)
+ : DataWrap<Derived, InfoProxyType>(parent, name, unit, desc)
{}
// The following functions are specific to vectors. If you use them
public:
typedef InfoProxyType<Derived> Info;
- DataWrapVec2d(Group *parent, const char *name, const char *desc)
- : DataWrapVec<Derived, InfoProxyType>(parent, name, desc)
+ DataWrapVec2d(Group *parent, const char *name,
+ const Units::Base *unit, const char *desc)
+ : DataWrapVec<Derived, InfoProxyType>(parent, name, unit, desc)
{
}
public:
ScalarBase(Group *parent = nullptr, const char *name = nullptr,
+ const Units::Base *unit = UNIT_UNSPECIFIED,
const char *desc = nullptr)
- : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc)
+ : DataWrap<Derived, ScalarInfoProxy>(parent, name, unit, desc)
{
this->doInit();
}
ProxyInfo *proxy;
public:
- ValueBase(Group *parent, const char *name, const char *desc)
- : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc),
+ ValueBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrap<Derived, ScalarInfoProxy>(parent, name, unit, desc),
proxy(NULL)
{
}
}
public:
- VectorBase(Group *parent, const char *name, const char *desc)
- : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc),
+ VectorBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrapVec<Derived, VectorInfoProxy>(parent, name, unit, desc),
storage(nullptr), _size(0)
{}
const Storage *data(off_type index) const { return &storage[index]; }
public:
- Vector2dBase(Group *parent, const char *name, const char *desc)
- : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc),
+ Vector2dBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, unit, desc),
x(0), y(0), _size(0), storage(nullptr)
{}
}
public:
- DistBase(Group *parent, const char *name, const char *desc)
- : DataWrap<Derived, DistInfoProxy>(parent, name, desc)
+ DistBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrap<Derived, DistInfoProxy>(parent, name, unit, desc)
{
}
}
public:
- VectorDistBase(Group *parent, const char *name, const char *desc)
- : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, desc),
+ VectorDistBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, unit, desc),
storage(NULL)
{}
public:
using ScalarBase<Scalar, StatStor>::operator=;
- Scalar(Group *parent = nullptr, const char *name = nullptr,
+ Scalar(Group *parent = nullptr)
+ : ScalarBase<Scalar, StatStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Scalar(Group *parent, const char *name, const char *desc = nullptr)
+ : ScalarBase<Scalar, StatStor>(parent, name, UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ Scalar(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : ScalarBase<Scalar, StatStor>(parent, name, desc)
+ : ScalarBase<Scalar, StatStor>(parent, name, unit, desc)
{
}
};
public:
using ScalarBase<Average, AvgStor>::operator=;
- Average(Group *parent = nullptr, const char *name = nullptr,
+ Average(Group *parent = nullptr)
+ : ScalarBase<Average, AvgStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Average(Group *parent, const char *name, const char *desc = nullptr)
+ : ScalarBase<Average, AvgStor>(parent, name, UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ Average(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : ScalarBase<Average, AvgStor>(parent, name, desc)
+ : ScalarBase<Average, AvgStor>(parent, name, unit, desc)
{
}
};
class Value : public ValueBase<Value>
{
public:
- Value(Group *parent = nullptr, const char *name = nullptr,
+ Value(Group *parent = nullptr)
+ : ValueBase<Value>(parent, nullptr, UNIT_UNSPECIFIED, nullptr)
+ {
+ }
+
+ Value(Group *parent, const char *name, const char *desc = nullptr)
+ : ValueBase<Value>(parent, name, UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ Value(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : ValueBase<Value>(parent, name, desc)
+ : ValueBase<Value>(parent, name, unit, desc)
{
}
};
class Vector : public VectorBase<Vector, StatStor>
{
public:
- Vector(Group *parent = nullptr, const char *name = nullptr,
+ Vector(Group *parent = nullptr)
+ : VectorBase<Vector, StatStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Vector(Group *parent, const char *name, const char *desc = nullptr)
+ : VectorBase<Vector, StatStor>(parent, name, UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ Vector(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : VectorBase<Vector, StatStor>(parent, name, desc)
+ : VectorBase<Vector, StatStor>(parent, name, unit, desc)
{
}
};
class AverageVector : public VectorBase<AverageVector, AvgStor>
{
public:
- AverageVector(Group *parent = nullptr, const char *name = nullptr,
+ AverageVector(Group *parent = nullptr)
+ : VectorBase<AverageVector, AvgStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ AverageVector(Group *parent, const char *name, const char *desc = nullptr)
+ : VectorBase<AverageVector, AvgStor>(parent, name, UNIT_UNSPECIFIED,
+ desc)
+ {
+ }
+
+ AverageVector(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : VectorBase<AverageVector, AvgStor>(parent, name, desc)
+ : VectorBase<AverageVector, AvgStor>(parent, name, unit, desc)
{
}
};
class Vector2d : public Vector2dBase<Vector2d, StatStor>
{
public:
- Vector2d(Group *parent = nullptr, const char *name = nullptr,
+ Vector2d(Group *parent = nullptr)
+ : Vector2dBase<Vector2d, StatStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Vector2d(Group *parent, const char *name, const char *desc = nullptr)
+ : Vector2dBase<Vector2d, StatStor>(parent, name, UNIT_UNSPECIFIED,
+ desc)
+ {
+ }
+
+ Vector2d(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : Vector2dBase<Vector2d, StatStor>(parent, name, desc)
+ : Vector2dBase<Vector2d, StatStor>(parent, name, unit, desc)
{
}
};
class Distribution : public DistBase<Distribution, DistStor>
{
public:
- Distribution(Group *parent = nullptr, const char *name = nullptr,
+ Distribution(Group *parent = nullptr)
+ : DistBase<Distribution, DistStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Distribution(Group *parent, const char *name, const char *desc = nullptr)
+ : DistBase<Distribution, DistStor>(parent, name, UNIT_UNSPECIFIED,
+ desc)
+ {
+ }
+
+ Distribution(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : DistBase<Distribution, DistStor>(parent, name, desc)
+ : DistBase<Distribution, DistStor>(parent, name, unit, desc)
{
}
class Histogram : public DistBase<Histogram, HistStor>
{
public:
- Histogram(Group *parent = nullptr, const char *name = nullptr,
+ Histogram(Group *parent = nullptr)
+ : DistBase<Histogram, HistStor>(parent, nullptr, UNIT_UNSPECIFIED,
+ nullptr)
+ {
+ }
+
+ Histogram(Group *parent, const char *name,
+ const char *desc = nullptr)
+ : DistBase<Histogram, HistStor>(parent, name, UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ Histogram(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : DistBase<Histogram, HistStor>(parent, name, desc)
+ : DistBase<Histogram, HistStor>(parent, name, unit, desc)
{
}
/**
* Construct and initialize this distribution.
*/
- StandardDeviation(Group *parent = nullptr, const char *name = nullptr,
+ StandardDeviation(Group *parent = nullptr)
+ : DistBase<StandardDeviation, SampleStor>(parent, nullptr,
+ UNIT_UNSPECIFIED, nullptr)
+ {
+ SampleStor::Params *params = new SampleStor::Params;
+ this->doInit();
+ this->setParams(params);
+ }
+
+ StandardDeviation(Group *parent, const char *name,
+ const char *desc = nullptr)
+ : DistBase<StandardDeviation, SampleStor>(parent, name,
+ UNIT_UNSPECIFIED, desc)
+ {
+ SampleStor::Params *params = new SampleStor::Params;
+ this->doInit();
+ this->setParams(params);
+ }
+
+ StandardDeviation(Group *parent, const char *name, const Units::Base *unit,
const char *desc = nullptr)
- : DistBase<StandardDeviation, SampleStor>(parent, name, desc)
+ : DistBase<StandardDeviation, SampleStor>(parent, name, unit, desc)
{
SampleStor::Params *params = new SampleStor::Params;
this->doInit();
/**
* Construct and initialize this distribution.
*/
- AverageDeviation(Group *parent = nullptr, const char *name = nullptr,
+ AverageDeviation(Group *parent = nullptr)
+ : DistBase<AverageDeviation, AvgSampleStor>(parent, nullptr,
+ UNIT_UNSPECIFIED, nullptr)
+ {
+ AvgSampleStor::Params *params = new AvgSampleStor::Params;
+ this->doInit();
+ this->setParams(params);
+ }
+
+ AverageDeviation(Group *parent, const char *name,
const char *desc = nullptr)
- : DistBase<AverageDeviation, AvgSampleStor>(parent, name, desc)
+ : DistBase<AverageDeviation, AvgSampleStor>(parent, name,
+ UNIT_UNSPECIFIED, desc)
+ {
+ AvgSampleStor::Params *params = new AvgSampleStor::Params;
+ this->doInit();
+ this->setParams(params);
+ }
+
+ AverageDeviation(Group *parent, const char *name, const Units::Base *unit,
+ const char *desc = nullptr)
+ : DistBase<AverageDeviation, AvgSampleStor>(parent, name, unit, desc)
{
AvgSampleStor::Params *params = new AvgSampleStor::Params;
this->doInit();
class VectorDistribution : public VectorDistBase<VectorDistribution, DistStor>
{
public:
- VectorDistribution(Group *parent = nullptr, const char *name = nullptr,
+ VectorDistribution(Group *parent = nullptr)
+ : VectorDistBase<VectorDistribution, DistStor>(parent, nullptr,
+ UNIT_UNSPECIFIED, nullptr)
+ {
+ }
+
+ VectorDistribution(Group *parent, const char *name,
+ const char *desc = nullptr)
+ : VectorDistBase<VectorDistribution, DistStor>(parent, name,
+ UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ VectorDistribution(Group *parent, const char *name,
+ const Units::Base *unit,
const char *desc = nullptr)
- : VectorDistBase<VectorDistribution, DistStor>(parent, name, desc)
+ : VectorDistBase<VectorDistribution, DistStor>(parent, name, unit,
+ desc)
{
}
: public VectorDistBase<VectorStandardDeviation, SampleStor>
{
public:
- VectorStandardDeviation(Group *parent = nullptr, const char *name = nullptr,
+ VectorStandardDeviation(Group *parent = nullptr)
+ : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, nullptr,
+ UNIT_UNSPECIFIED, nullptr)
+ {
+ }
+
+ VectorStandardDeviation(Group *parent, const char *name,
const char *desc = nullptr)
: VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name,
- desc)
+ UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ VectorStandardDeviation(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc = nullptr)
+ : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name,
+ unit, desc)
{
}
: public VectorDistBase<VectorAverageDeviation, AvgSampleStor>
{
public:
- VectorAverageDeviation(Group *parent = nullptr, const char *name = nullptr,
+ VectorAverageDeviation(Group *parent = nullptr)
+ : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent,
+ nullptr, UNIT_UNSPECIFIED, nullptr)
+ {
+ }
+
+ VectorAverageDeviation(Group *parent, const char *name,
const char *desc = nullptr)
: VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name,
- desc)
+ UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ VectorAverageDeviation(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc = nullptr)
+ : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name,
+ unit, desc)
{
}
}
public:
- SparseHistBase(Group *parent, const char *name, const char *desc)
- : DataWrap<Derived, SparseHistInfoProxy>(parent, name, desc)
+ SparseHistBase(Group *parent, const char *name,
+ const Units::Base *unit,
+ const char *desc)
+ : DataWrap<Derived, SparseHistInfoProxy>(parent, name, unit, desc)
{
}
class SparseHistogram : public SparseHistBase<SparseHistogram, SparseHistStor>
{
public:
- SparseHistogram(Group *parent = nullptr, const char *name = nullptr,
+ SparseHistogram(Group *parent = nullptr)
+ : SparseHistBase<SparseHistogram, SparseHistStor>(parent, nullptr,
+ UNIT_UNSPECIFIED, nullptr)
+ {
+ }
+
+ SparseHistogram(Group *parent, const char *name,
const char *desc = nullptr)
- : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, desc)
+ : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name,
+ UNIT_UNSPECIFIED, desc)
+ {
+ }
+
+ SparseHistogram(Group *parent, const char *name, const Units::Base *unit,
+ const char *desc = nullptr)
+ : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, unit,
+ desc)
{
}
Formula(Group *parent = nullptr, const char *name = nullptr,
const char *desc = nullptr);
+ Formula(Group *parent, const char *name, const Units::Base *unit,
+ const char *desc = nullptr);
+
Formula(Group *parent, const char *name, const char *desc,
const Temp &r);
+ Formula(Group *parent, const char *name, const Units::Base *unit,
+ const char *desc, const Temp &r);
+
/**
* Set an unitialized Formula to the given root.
* @param r The root of the expression tree.
--- /dev/null
+/*
+ * Copyright (c) 2021 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BASE_STATS_UNITS_HH__
+#define __BASE_STATS_UNITS_HH__
+
+#include <type_traits>
+
+#include "base/cprintf.hh"
+
+/**
+ * Convenience macros to declare the unit of a stat.
+ */
+#define UNIT_CYCLE Stats::Units::Cycle::get()
+#define UNIT_TICK Stats::Units::Tick::get()
+#define UNIT_SECOND Stats::Units::Second::get()
+#define UNIT_BIT Stats::Units::Bit::get()
+#define UNIT_BYTE Stats::Units::Byte::get()
+#define UNIT_JOULE Stats::Units::Joule::get()
+#define UNIT_VOLT Stats::Units::Volt::get()
+#define UNIT_CELSIUS Stats::Units::DegreeCelsius::get()
+#define UNIT_RATE(T1, T2) Stats::Units::Rate<T1, T2>::get()
+#define UNIT_RATIO Stats::Units::Ratio::get()
+#define UNIT_COUNT Stats::Units::Count::get()
+#define UNIT_UNSPECIFIED Stats::Units::Unspecified::get()
+
+#define UNIT_WATT UNIT_RATE(Stats::Units::Joule, Stats::Units::Second)
+
+namespace Stats {
+
+/**
+ * Units for Stats.
+ *
+ * This header file provides an ability to associate a stat object with a
+ * specific unit.
+ *
+ * The supported units are:
+ * - Cycle: represents clock cycles.
+ * - Tick: represents the count of gem5's Tick.
+ * - Second: represents the base unit of time defined by SI.
+ * - Bit: represents the number of computer bits.
+ * - Byte: represents 8 bits.
+ * - Volt: a SI derived unit measuring potential difference.
+ * - Joule: represents joule, a unit of energy, as defined by SI.
+ * - Watt: represents 1 watt, where 1 watt = 1 joule / second.
+ * - Celsius: represents 1 Celsius degree as defined by SI.
+ * - Rate(T1, T2): represents the unit of a quantity of T1 divided by
+ * a quantity of T2.
+ * - Ratio: represents the unit of a quantity of unit T divided by a quantity
+ * of T.
+ * - Count: represents the count of a quantity that is not defined above.
+ * - Unspecified: the unit of the stat is unspecified.
+ *
+ * Each unit class is intended to be a singleton, which means only each unit
+ * class has at most one object of that class exist throughout the program.
+ * Therefore, copy constructors and assignment operators are deleted functions.
+ *
+ * When any of the following criteria is met, a new unit should be added,
+ * - The new unit is significant enough to be not included in Count unit.
+ * (e.g. Cycle unit, Tick unit)
+ */
+namespace Units {
+
+/**
+ * The Base class is the parent class of all unit classes.
+ * This class is intended to an abstract class specifying common behaviors of
+ * all unit classes.
+ */
+class Base
+{
+ public:
+ virtual std::string getUnitString() const = 0;
+};
+
+class Cycle : public Base
+{
+ private:
+ Cycle() {}
+ public:
+ Cycle(Cycle const&) = delete;
+ void operator=(Cycle const&) = delete;
+ static Cycle*
+ get()
+ {
+ static Cycle instance;
+ return &instance;
+ }
+ static std::string toString() { return "Cycle"; }
+ std::string getUnitString() const override { return Cycle::toString(); }
+};
+
+class Tick : public Base
+{
+ private:
+ Tick() {}
+ public:
+ Tick(Tick const&) = delete;
+ void operator=(Tick const&) = delete;
+ static Tick*
+ get()
+ {
+ static Tick instance;
+ return &instance;
+ }
+ static std::string toString() { return "Tick"; }
+ std::string getUnitString() const override { return Tick::toString(); }
+};
+
+class Second : public Base
+{
+ private:
+ Second() {}
+ public:
+ Second(Second const&) = delete;
+ void operator=(Second const&) = delete;
+ static Second*
+ get()
+ {
+ static Second instance;
+ return &instance;
+ }
+ static std::string toString() { return "Second"; }
+ std::string getUnitString() const override { return Second::toString(); }
+};
+
+class Bit : public Base
+{
+ private:
+ Bit() {}
+ public:
+ Bit(Bit const&) = delete;
+ void operator=(Bit const&) = delete;
+ static Bit*
+ get()
+ {
+ static Bit instance;
+ return &instance;
+ }
+ static std::string toString() { return "Bit"; }
+ std::string getUnitString() const override { return Bit::toString(); }
+};
+
+class Byte : public Base
+{
+ private:
+ Byte() {}
+ public:
+ Byte(Byte const&) = delete;
+ void operator=(Byte const&) = delete;
+ static Byte*
+ get()
+ {
+ static Byte instance;
+ return &instance;
+ }
+ static std::string toString() { return "Byte"; }
+ std::string getUnitString() const override { return Byte::toString(); }
+};
+
+class Watt : public Base
+{
+ private:
+ Watt() {}
+ public:
+ Watt(Watt const&) = delete;
+ void operator=(Watt const&) = delete;
+ static Watt*
+ get()
+ {
+ static Watt instance;
+ return &instance;
+ }
+ static std::string toString() { return "Watt"; }
+ std::string getUnitString() const override { return Watt::toString(); }
+};
+
+
+class Joule : public Base
+{
+ private:
+ Joule() {}
+ public:
+ Joule(Joule const&) = delete;
+ void operator=(Joule const&) = delete;
+ static Joule*
+ get()
+ {
+ static Joule instance;
+ return &instance;
+ }
+ static std::string toString() { return "Joule"; }
+ std::string getUnitString() const override { return Joule::toString(); }
+};
+
+class Volt : public Base
+{
+ private:
+ Volt() {}
+ public:
+ Volt(Volt const&) = delete;
+ void operator=(Volt const&) = delete;
+ static Volt*
+ get()
+ {
+ static Volt instance;
+ return &instance;
+ }
+ static std::string toString() { return "Volt"; }
+ std::string getUnitString() const override { return Volt::toString(); }
+};
+
+class DegreeCelsius : public Base
+{
+ private:
+ DegreeCelsius() {}
+ public:
+ DegreeCelsius(DegreeCelsius const&) = delete;
+ void operator=(DegreeCelsius const&) = delete;
+ static DegreeCelsius*
+ get()
+ {
+ static DegreeCelsius instance;
+ return &instance;
+ }
+ static std::string toString() { return "Celsius"; }
+ std::string
+ getUnitString() const override
+ {
+ return DegreeCelsius::toString();
+ }
+};
+
+
+class Count : public Base
+{
+ private:
+ Count() {}
+ public:
+ Count(Count const&) = delete;
+ void operator=(Count const&) = delete;
+ static Count*
+ get()
+ {
+ static Count instance;
+ return &instance;
+ }
+ static std::string toString() { return "Count"; }
+ std::string getUnitString() const override { return Count::toString(); }
+};
+
+template <typename T1, typename T2>
+class Rate : public Base
+{
+ static_assert(std::is_base_of<Base, T1>::value,
+ "Rate(T1,T2) must have T1 and T2 derived from"
+ "Stats::Units::Base");
+ static_assert(std::is_base_of<Base, T2>::value,
+ "Rate(T1,T2) must have T1 and T2 derived from"
+ "Stats::Units::Base");
+ private:
+ Rate<T1,T2>() {}
+ public:
+ Rate<T1,T2>(Rate<T1,T2> const&) = delete;
+ void operator=(Rate<T1,T2> const&) = delete;
+ static Rate<T1,T2>*
+ get()
+ {
+ static Rate<T1,T2> instance;
+ return &instance;
+ }
+ static std::string
+ toString()
+ {
+ return csprintf("(%s/%s)", T1::toString(), T2::toString());
+ }
+ std::string
+ getUnitString() const override
+ {
+ return Rate<T1,T2>::toString();
+ }
+};
+
+class Ratio : public Base
+{
+ private:
+ Ratio() {}
+ public:
+ Ratio(Ratio const&) = delete;
+ void operator=(Ratio const&) = delete;
+ static Ratio*
+ get()
+ {
+ static Ratio instance;
+ return &instance;
+ }
+ static std::string toString() { return "Ratio"; }
+ std::string getUnitString() const override { return Ratio::toString(); }
+};
+
+class Unspecified : public Base
+{
+ private:
+ Unspecified() {}
+ public:
+ Unspecified(Unspecified const&) = delete;
+ void operator=(Unspecified const&) = delete;
+ static Unspecified*
+ get()
+ {
+ static Unspecified instance;
+ return &instance;
+ }
+ static std::string toString() { return "Unspecified"; }
+ std::string
+ getUnitString() const override
+ {
+ return Unspecified::toString();
+ }
+};
+
+} // namespace Units
+
+} // namespace Stats
+
+#endif // __BASE_STATS_UNITS_HH__