From 5677cd41e3916bd58926bf335f5727d0f2bb7764 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 27 Mar 2013 12:03:16 +0100 Subject: [PATCH] Changed PQ to template, removed unit default values, checked unit tests --- samples/physicalquantities/main.cpp | 24 +- src/blackmisc/blackmisc.pro | 13 +- src/blackmisc/pqangle.cpp | 45 --- src/blackmisc/pqangle.h | 74 +---- src/blackmisc/pqbase.h | 4 +- src/blackmisc/pqconstants.cpp | 7 - src/blackmisc/pqconstants.h | 10 +- src/blackmisc/pqdistance.cpp | 45 --- src/blackmisc/pqdistance.h | 82 +---- src/blackmisc/pqfrequency.cpp | 46 --- src/blackmisc/pqfrequency.h | 74 +---- src/blackmisc/pqmass.cpp | 45 --- src/blackmisc/pqmass.h | 77 +---- src/blackmisc/pqphysicalquantity.cpp | 306 +++++++++--------- src/blackmisc/pqphysicalquantity.h | 210 ++++++------ src/blackmisc/pqpressure.cpp | 46 --- src/blackmisc/pqpressure.h | 90 +----- src/blackmisc/pqspeed.cpp | 45 --- src/blackmisc/pqspeed.h | 82 +---- src/blackmisc/pqtemperature.cpp | 56 +--- src/blackmisc/pqtemperature.h | 71 +--- .../blackmisc/testphysicalquantitiesbase.cpp | 40 ++- tests/blackmisc/testphysicalquantitiesbase.h | 7 +- 23 files changed, 408 insertions(+), 1091 deletions(-) delete mode 100644 src/blackmisc/pqangle.cpp delete mode 100644 src/blackmisc/pqconstants.cpp delete mode 100644 src/blackmisc/pqdistance.cpp delete mode 100644 src/blackmisc/pqfrequency.cpp delete mode 100644 src/blackmisc/pqmass.cpp delete mode 100644 src/blackmisc/pqpressure.cpp delete mode 100644 src/blackmisc/pqspeed.cpp diff --git a/samples/physicalquantities/main.cpp b/samples/physicalquantities/main.cpp index 69349d472..ae58acd98 100644 --- a/samples/physicalquantities/main.cpp +++ b/samples/physicalquantities/main.cpp @@ -15,20 +15,30 @@ using namespace BlackMisc; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); + + // cases which must not work + // CMeasurementUnit mu; //must not work + // CDistanceUnit du1(CAngleUnit::rad()); + CDistanceUnit du2(CDistanceUnit::cm()); + CDistanceUnit du3(CDistanceUnit::ft()); const CDistance d1(5.0, CDistanceUnit::ft()); // 5 ft CDistance d2(1, CDistanceUnit::NM()); // 1NM CDistance d3(1, CDistanceUnit::km()); - qDebug() << d1 << d2 << d3; + CDistance d4(d3); + + qDebug() << CDistanceUnit::ft(); + qDebug() << d1 << d2 << d3 << d4; qDebug() << d1.valueRoundedWithUnit(CDistanceUnit::ft(),5) << d2.valueRoundedWithUnit(CDistanceUnit::km()); qDebug() << d3.getUnit(); + d2.switchUnit(CDistanceUnit::ft()); // now in ft d3 += d3; // 2km now d3 *= 1.5;// 3km now qDebug() << d2 << d3; - CFrequency f1(1E6); // 1MHz + CFrequency f1(1E6, CFrequencyUnit::Hz()); // 1MHz qDebug() << f1 << f1.valueRoundedWithUnit(CFrequencyUnit::MHz()) << f1.valueRoundedWithUnit(CFrequencyUnit::GHz(), 3); CSpeed s1 = CSpeed(100, CSpeedUnit::km_h()); @@ -39,7 +49,14 @@ int main(int argc, char *argv[]) qDebug() << s2 << s3; CAngle a1(180, CAngleUnit::deg()); - CAngle a2(1.5 * CAngle::pi()); + CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad()); + a1 += a2; + // a1 = d2; // must not work + qDebug() << a1; + a1.switchUnit(CAngleUnit::deg()); + // a2 += d1; // must not work + a2 = a1 + a1; + a2.switchUnit(CAngleUnit::deg()); qDebug() << a1.unitValueRoundedWithUnit() << a1.piFactor(); qDebug() << a2; @@ -65,6 +82,7 @@ int main(int argc, char *argv[]) // some of the faults Mathew has pointed out,not longer possible // CAngleUnit::rad() = CAngleUnit::deg(); // qDebug() << CAngleUnit::rad(); // wrong + (t1 - t2).switchUnit(CTemperatureUnit::F()); // was not working since wrong return type const // CDistanceUnit duA(CSpeedUnit::ft_min()); // no longer possible CDistanceUnit duB(CDistanceUnit::cm()); diff --git a/src/blackmisc/blackmisc.pro b/src/blackmisc/blackmisc.pro index 32d26c9d7..c8aceb8cd 100644 --- a/src/blackmisc/blackmisc.pro +++ b/src/blackmisc/blackmisc.pro @@ -45,7 +45,10 @@ HEADERS += \ pqmass.h \ pqpressure.h \ pqtemperature.h \ - pqconstants.h + pqconstants.h \ + avverticalposition.h \ + pqunits.h \ + pqallquantities.h SOURCES += \ logmessage.cpp \ @@ -66,15 +69,9 @@ SOURCES += \ type_info.cpp \ message_dispatcher.cpp \ message_system.cpp \ - pqdistance.cpp \ pqphysicalquantity.cpp \ - pqfrequency.cpp \ pqbase.cpp \ - pqspeed.cpp \ - pqangle.cpp \ - pqmass.cpp \ - pqpressure.cpp \ pqtemperature.cpp \ - pqconstants.cpp + avverticalposition.cpp DESTDIR = ../../lib diff --git a/src/blackmisc/pqangle.cpp b/src/blackmisc/pqangle.cpp deleted file mode 100644 index 14cd19686..000000000 --- a/src/blackmisc/pqangle.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "blackmisc/pqangle.h" - -namespace BlackMisc { - -/** - * Default constructor - */ -CAngle::CAngle() : CPhysicalQuantity(0, CAngleUnit::rad(), CAngleUnit::rad()) -{ - // void -} - -/** - * Constructor - */ -CAngle::CAngle(const CPhysicalQuantity &angle): CPhysicalQuantity(angle) -{ - //void -} - -/** - * Constructor - */ -CAngle::CAngle(qint32 value, const CAngleUnit &unit) : CPhysicalQuantity(value, unit, CAngleUnit::rad()) -{ - // void -} - -/** - * Constructor - */ -CAngle::CAngle(double value, const CAngleUnit &unit) : CPhysicalQuantity(value, unit, CAngleUnit::rad()) -{ - // void -} - -/** - * Destructor - */ -CAngle::~CAngle() -{ - // void -} - -} // namespace diff --git a/src/blackmisc/pqangle.h b/src/blackmisc/pqangle.h index befb94f12..150acaffd 100644 --- a/src/blackmisc/pqangle.h +++ b/src/blackmisc/pqangle.h @@ -1,89 +1,41 @@ #ifndef PQANGLE_H #define PQANGLE_H -#include "pqphysicalquantity.h" -#include "math.h" +#include "blackmisc/pqphysicalquantity.h" namespace BlackMisc { -/*! - * Specialized class for angles (degrees, radian). - * \author KWB - */ -class CAngleUnit : public CMeasurementUnit { - friend class CAngle; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CAngleUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief Angle units: Radian, degree - * \param name - * \param unitName - * \param isSIUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CAngleUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "angle", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Meter m - * \return - */ - static const CAngleUnit& rad() { static CAngleUnit rad("radian", "rad", true); return rad;} - /*! - * \brief Nautical miles NM - * \return - */ - static const CAngleUnit& deg() { static CAngleUnit deg("degree", "°", false, M_PI/180); return deg;} -}; - /*! * \brief Physical unit degree * \author KWB */ -class CAngle : public CPhysicalQuantity +class CAngle : public CPhysicalQuantity { + public: /*! * \brief Default constructor */ - CAngle(); + CAngle() : CPhysicalQuantity(0, CAngleUnit::rad(), CAngleUnit::rad()) {} /** - *\brief downcast copy constructor - */ - CAngle(const CPhysicalQuantity &angle); + * \brief Copy constructor + */ + CAngle(const CAngle &angle) : CPhysicalQuantity(angle) {} /*! * \brief Init by int value * \param value * \param unit */ - CAngle(qint32 value, const CAngleUnit &unit = CAngleUnit::rad()); + CAngle(qint32 value, const CAngleUnit &unit): CPhysicalQuantity(value, unit, CAngleUnit::rad()) {} /*! - *\brief Init by double value + * \brief Init by double value * \param value * \param unit */ - CAngle(double value, const CAngleUnit &unit = CAngleUnit::rad()); + CAngle(double value, const CAngleUnit &unit): CPhysicalQuantity(value, unit, CAngleUnit::rad()) {} /*! * \brief Virtual destructor */ - virtual ~CAngle(); - /*! - * \brief Unit of the distance - * \return - */ - CAngleUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CAngleUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CAngle() {} /*! * \brief Convenience method PI * \return @@ -94,8 +46,8 @@ public: * \return */ double piFactor() const { return CPhysicalQuantity::round(this->convertedSiValueToDouble() / M_PI,6);} - }; -} // namespace blackCore + +} // namespace #endif // PQANGLE_H diff --git a/src/blackmisc/pqbase.h b/src/blackmisc/pqbase.h index 794211fa0..ecb5e1ef1 100644 --- a/src/blackmisc/pqbase.h +++ b/src/blackmisc/pqbase.h @@ -198,8 +198,6 @@ protected: * \param epsilon */ CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1, const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2, double epsilon = 1E-10); - -public: /*! * \brief Copy constructor * \param otherUnit @@ -211,6 +209,8 @@ public: * \return */ CMeasurementUnit &operator =(const CMeasurementUnit &otherUnit); + +public: /*! * \brief Equal operator == * \param otherUnit diff --git a/src/blackmisc/pqconstants.cpp b/src/blackmisc/pqconstants.cpp deleted file mode 100644 index b4fdb4a29..000000000 --- a/src/blackmisc/pqconstants.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "blackmisc/pqconstants.h" - -namespace BlackMisc { - - // no code here, all in header - -} // namespace diff --git a/src/blackmisc/pqconstants.h b/src/blackmisc/pqconstants.h index e41f52bba..29eb5cb64 100644 --- a/src/blackmisc/pqconstants.h +++ b/src/blackmisc/pqconstants.h @@ -1,19 +1,13 @@ #ifndef PQCONSTANTS_H #define PQCONSTANTS_H -#include "blackmisc/blackmisc.h" -#include "blackmisc/pqdistance.h" -#include "blackmisc/pqfrequency.h" -#include "blackmisc/pqspeed.h" -#include "blackmisc/pqangle.h" -#include "blackmisc/pqmass.h" -#include "blackmisc/pqpressure.h" -#include "blackmisc/pqtemperature.h" +#include "blackmisc/pqallquantities.h" namespace BlackMisc{ class CPhysicalQuantitiesConstants { + public: /*! * \brief Temperature absolute Zero in °C diff --git a/src/blackmisc/pqdistance.cpp b/src/blackmisc/pqdistance.cpp deleted file mode 100644 index 48b0ce498..000000000 --- a/src/blackmisc/pqdistance.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "blackmisc/pqdistance.h" - -namespace BlackMisc { - -/** - * Default Constructor - */ -CDistance::CDistance(): CPhysicalQuantity(0, CDistanceUnit::m(),CDistanceUnit::m()) -{ - //void -} - -/** - * Constructor - */ -CDistance::CDistance(const CPhysicalQuantity &distance): CPhysicalQuantity(distance) -{ - //void -} - -/** - * Constructor - */ -CDistance::CDistance(qint32 value, const CDistanceUnit &unit) : CPhysicalQuantity(value, unit, CDistanceUnit::m()) -{ - // void -} - -/** - * Constructor - */ -CDistance::CDistance(double value, const CDistanceUnit &unit) : CPhysicalQuantity(value, unit, CDistanceUnit::m()) -{ - // void -} - -/** - * Destructor - */ -CDistance::~CDistance() -{ - // void -} - -} // namespace BlackCore diff --git a/src/blackmisc/pqdistance.h b/src/blackmisc/pqdistance.h index e4cc77424..210f7313d 100644 --- a/src/blackmisc/pqdistance.h +++ b/src/blackmisc/pqdistance.h @@ -1,104 +1,40 @@ #ifndef PQDISTANCE_H #define PQDISTANCE_H -#include "pqphysicalquantity.h" +#include "blackmisc/pqphysicalquantity.h" namespace BlackMisc { -/*! - * Specialized class for distance units (meter, foot, nautical miles). - * \author KWB - */ -class CDistanceUnit : public CMeasurementUnit { - friend class CDistance; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CDistanceUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief Distance unit - * \param name - * \param unitName - * \param isSIUnit - * \param isSIBaseUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CDistanceUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "distance", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Meter m - * \return - */ - static const CDistanceUnit& m() { static CDistanceUnit m("meter", "m", true, true); return m;} - /*! - * \brief Nautical miles NM - * \return - */ - static const CDistanceUnit& NM() { static CDistanceUnit NM("nautical miles", "NM", false, false, 1000.0*1.85200, CMeasurementPrefix::One(), 3);return NM;} - /*! - * \brief Foot ft - * \return - */ - static const CDistanceUnit& ft() { static CDistanceUnit ft("foot", "ft", false, false, 0.3048, CMeasurementPrefix::One(), 0); return ft;} - /*! - * \brief Kilometer km - * \return - */ - static const CDistanceUnit& km() { static CDistanceUnit km("kilometer", "km", true, false, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 3);return km;} - /*! - * \brief Centimeter cm - * \return - */ - static const CDistanceUnit& cm() { static CDistanceUnit cm("centimeter", "cm", true, false, CMeasurementPrefix::c().getFactor(), CMeasurementPrefix::c(), 1);return cm;} -}; - /*! * \brief Physical unit distance * \author KWB */ -class CDistance : public CPhysicalQuantity +class CDistance : public CPhysicalQuantity { public: /*! * \brief Default constructor */ - CDistance(); + CDistance() : CPhysicalQuantity (0, CDistanceUnit::m(), CDistanceUnit::m()) {} /** - *\brief downcast copy constructor + *\brief Copy constructor */ - CDistance(const CPhysicalQuantity &distance); + CDistance(const CDistance &distance) : CPhysicalQuantity(distance) {} /*! * \brief Init by int value * \param value * \param unit */ - CDistance(qint32 value, const CDistanceUnit &unit = CDistanceUnit::m()); + CDistance(qint32 value, const CDistanceUnit &unit) : CPhysicalQuantity(value, unit, CDistanceUnit::m()) {} /*! *\brief Init by double value * \param value * \param unit */ - CDistance(double value, const CDistanceUnit &unit = CDistanceUnit::m()); + CDistance(double value, const CDistanceUnit &unit) : CPhysicalQuantity(value, unit, CDistanceUnit::m()) {} /*! * \brief Virtual destructor */ - virtual ~CDistance(); - /*! - * \brief Unit of the distance - * \return - */ - CDistanceUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CDistanceUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CDistance() {} }; -} // namespace blackCore +} // namespace #endif // PQDISTANCE_H diff --git a/src/blackmisc/pqfrequency.cpp b/src/blackmisc/pqfrequency.cpp deleted file mode 100644 index 8c699b53a..000000000 --- a/src/blackmisc/pqfrequency.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "blackmisc/pqfrequency.h" - -namespace BlackMisc { - -/** - * Default constructor - */ -CFrequency::CFrequency() : CPhysicalQuantity(0, CFrequencyUnit::Hz(), CFrequencyUnit::Hz()) -{ - // void -} - -/** - * Constructor - */ -CFrequency::CFrequency(const CPhysicalQuantity &frequency): CPhysicalQuantity(frequency) -{ - //void -} - -/** - * Constructor - */ -CFrequency::CFrequency(qint32 value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit, CFrequencyUnit::Hz()) -{ - // void -} - -/** - * Constructor - */ -CFrequency::CFrequency(double value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit, CFrequencyUnit::Hz()) -{ - // void -} - -/** - * Destructor - */ -CFrequency::~CFrequency() -{ - // void -} - - -} // namespace diff --git a/src/blackmisc/pqfrequency.h b/src/blackmisc/pqfrequency.h index 385961f11..3a4c48623 100644 --- a/src/blackmisc/pqfrequency.h +++ b/src/blackmisc/pqfrequency.h @@ -4,95 +4,37 @@ namespace BlackMisc { -/*! - * Specialized class for frequency (hertz, mega hertz, kilo hertz). - * \author KWB - */ -class CFrequencyUnit : public CMeasurementUnit { - friend class CFrequency; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CFrequencyUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief CFrequencyUnit - * \param name - * \param unitName - * \param isSIUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CFrequencyUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "frequency", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Hertz - * \return - */ - static const CFrequencyUnit& Hz() { static CFrequencyUnit Hz("hertz", "Hz", true); return Hz;} - /*! - * \brief Kilohertz - * \return - */ - static const CFrequencyUnit& kHz() { static CFrequencyUnit kHz("kilohertz", "kHz", true, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 0);return kHz;} - /*! - * \brief Megahertz - * \return - */ - static const CFrequencyUnit& MHz() { static CFrequencyUnit MHz("megahertz", "MHz", false, CMeasurementPrefix::M().getFactor(), CMeasurementPrefix::M(), 0); return MHz;} - /*! - * \brief Gigahertz - * \return - */ - static const CFrequencyUnit& GHz() { static CFrequencyUnit GHz("gigahertz", "GHz", true, CMeasurementPrefix::G().getFactor(), CMeasurementPrefix::G(), 0);return GHz;} -}; - /*! * \brief Physical unit distance * \author KWB */ -class CFrequency : public CPhysicalQuantity +class CFrequency : public CPhysicalQuantity { public: /*! * \brief Default constructor */ - CFrequency(); + CFrequency() : CPhysicalQuantity(0, CFrequencyUnit::Hz(), CFrequencyUnit::Hz()) {} /** - *\brief downcast copy constructor + *\brief Copy constructor */ - CFrequency(const CPhysicalQuantity &frequency); + CFrequency(const CFrequency &frequency) : CPhysicalQuantity(frequency) {} /*! * \brief Init by int value * \param value * \param unit */ - CFrequency(qint32 value, const CFrequencyUnit &unit = CFrequencyUnit::Hz()); + CFrequency(qint32 value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit, CFrequencyUnit::Hz()){} /*! * \brief Init by double value * \param value * \param unit */ - CFrequency(double value, const CFrequencyUnit &unit = CFrequencyUnit::Hz()); + CFrequency(double value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit, CFrequencyUnit::Hz()){} /*! * \brief Virtual destructor */ - virtual ~CFrequency(); - /*! - * \brief Unit of the distance - * \return - */ - CFrequencyUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CFrequencyUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CFrequency() {} }; -} // namespace blackCore +} // namespace #endif // PQFREQUENCY_H diff --git a/src/blackmisc/pqmass.cpp b/src/blackmisc/pqmass.cpp deleted file mode 100644 index 62207fa42..000000000 --- a/src/blackmisc/pqmass.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "blackmisc/pqmass.h" - -namespace BlackMisc { - -/** - * Default Constructor - */ -CMass::CMass(): CPhysicalQuantity(0, CMassUnit::kg(),CMassUnit::kg()) -{ - // void -} - -/** - * Constructor - */ -CMass::CMass(const CPhysicalQuantity &mass): CPhysicalQuantity(mass) -{ - // void -} - -/** - * Constructor - */ -CMass::CMass(qint32 value, const CMassUnit &unit) : CPhysicalQuantity(value, unit, CMassUnit::kg()) -{ - // void -} - -/** - * Constructor - */ -CMass::CMass(double value, const CMassUnit &unit) : CPhysicalQuantity(value, unit, CMassUnit::kg()) -{ - // void -} - -/** - * Destructor - */ -CMass::~CMass() -{ - // void -} - -} // namespace BlackMisc diff --git a/src/blackmisc/pqmass.h b/src/blackmisc/pqmass.h index 067da25cf..b7bdef6f3 100644 --- a/src/blackmisc/pqmass.h +++ b/src/blackmisc/pqmass.h @@ -4,98 +4,39 @@ namespace BlackMisc { -/*! - * Specialized class for mass units (kg, lbs). - * \author KWB - */ -class CMassUnit : public CMeasurementUnit { - friend class CMass; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CMassUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief Mass units - * \param name - * \param unitName - * \param isSIUnit - * \param isSIBaseUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CMassUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "mass", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Kilogram, SI base unit - * \return - */ - static const CMassUnit& kg() { static CMassUnit kg("kilogram", "kg", true, true, 1.0, CMeasurementPrefix::k(), 1); return kg;} - /*! - * \brief Gram, SI unit - * \return - */ - static const CMassUnit& g() { static CMassUnit g("gram", "g", true, false, 1.0/1000.0, CMeasurementPrefix::One(), 0); return g;} - /*! - * \brief Tonne, aka metric tonne (1000kg) - * \return - */ - static const CMassUnit& t() { static CMassUnit t("tonne", "t", true, false, 1000.0, CMeasurementPrefix::One(), 3); return t;} - /*! - * \brief Pound, aka mass pound - * \return - */ - static const CMassUnit& lb() { static CMassUnit lbs("pound", "lb", false, false, 0.45359237, CMeasurementPrefix::One(), 1); return lbs;} -}; - /*! * \brief Mass * \author KWB */ -class CMass : public CPhysicalQuantity +class CMass : public CPhysicalQuantity { public: /*! * \brief Default constructor */ - CMass(); + CMass() : CPhysicalQuantity(0, CMassUnit::kg(), CMassUnit::kg()) {} /*! * \brief Init by int value * \param value * \param unit */ - CMass(qint32 value, const CMassUnit &unit = CMassUnit::kg()); + CMass(qint32 value, const CMassUnit &unit) : CPhysicalQuantity(value, unit, CMassUnit::kg()){} /*! - *\brief Init by double value + * \brief Init by double value * \param value * \param unit */ - CMass(double value, const CMassUnit &unit = CMassUnit::kg()); + CMass(double value, const CMassUnit &unit) : CPhysicalQuantity(value, unit, CMassUnit::kg()){} /*! - * \brief Copyconstructor + * \brief Copy constructor * \param mass */ - CMass(const CPhysicalQuantity &mass); + CMass(const CPhysicalQuantity &mass) : CPhysicalQuantity(mass){} /*! * \brief Virtual destructor */ - virtual ~CMass(); - /*! - * \brief Unit of the mass - * \return - */ - CMassUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CMassUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CMass() {} }; -} // namespace blackCore +} // namespace #endif // PQMASS_H diff --git a/src/blackmisc/pqphysicalquantity.cpp b/src/blackmisc/pqphysicalquantity.cpp index e641f61af..406faf560 100644 --- a/src/blackmisc/pqphysicalquantity.cpp +++ b/src/blackmisc/pqphysicalquantity.cpp @@ -1,12 +1,12 @@ -#include "blackmisc/pqphysicalquantity.h" +#include "blackmisc/pqallquantities.h" namespace BlackMisc { /** * Constructor by integer */ -CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : - _pUnit(unit), _pConversionSiUnit(siConversionUnit), _unitConverter(unitConverter) +template CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : + m_unit(unit), m_conversionSiUnit(siConversionUnit), m_unitConverter(unitConverter) { this->setUnitValue(baseValue); } @@ -14,8 +14,8 @@ CPhysicalQuantity::CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &u /** * Constructor by double */ -CPhysicalQuantity::CPhysicalQuantity(double baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : - _pUnit(unit), _pConversionSiUnit(siConversionUnit),_unitConverter(unitConverter) +template CPhysicalQuantity::CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : + m_unit(unit), m_conversionSiUnit(siConversionUnit),m_unitConverter(unitConverter) { this->setUnitValue(baseValue); } @@ -23,9 +23,9 @@ CPhysicalQuantity::CPhysicalQuantity(double baseValue, const CMeasurementUnit &u /** * Copy constructor */ -CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) : - _unitValueD(otherQuantity._unitValueD), _unitValueI(otherQuantity._unitValueI), _convertedSiUnitValueD(otherQuantity._convertedSiUnitValueD), - _isIntegerBaseValue(otherQuantity._isIntegerBaseValue), _pUnit(otherQuantity._pUnit), _pConversionSiUnit(otherQuantity._pConversionSiUnit), _unitConverter(otherQuantity._unitConverter) +template CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) : + m_unitValueD(otherQuantity.m_unitValueD), m_unitValueI(otherQuantity.m_unitValueI), m_convertedSiUnitValueD(otherQuantity.m_convertedSiUnitValueD), + m_isIntegerBaseValue(otherQuantity.m_isIntegerBaseValue), m_unit(otherQuantity.m_unit), m_conversionSiUnit(otherQuantity.m_conversionSiUnit), m_unitConverter(otherQuantity.m_unitConverter) { // void } @@ -33,62 +33,42 @@ CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) : /*! * Destructor */ -CPhysicalQuantity::~CPhysicalQuantity() +template CPhysicalQuantity::~CPhysicalQuantity() { // void } -/** - * Stream operator - */ -QDebug operator <<(QDebug d, const CPhysicalQuantity &quantity) -{ - QString v = quantity.unitValueRoundedWithUnit(-1); - d << v; - return d; -} - -/** - * Stream operator - */ -CLogMessage operator <<(CLogMessage d, const CPhysicalQuantity &quantity) -{ - QString v = quantity.unitValueRoundedWithUnit(-1); - d << v; - return d; -} - /** * Equal operator == */ -bool CPhysicalQuantity::operator ==(const CPhysicalQuantity &otherQuantity) const +template bool CPhysicalQuantity::operator ==(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return true; - if(this->_pUnit.getType()!= otherQuantity._pUnit.getType()) return false; + if(this->m_unit.getType()!= otherQuantity.m_unit.getType()) return false; // some special case for best quality double diff; - const double lenient = 1.001; // even diff alread has a round issue - if (this->_pUnit == otherQuantity._pUnit) { + const double lenient = 1.001; // even diff already has a rounding issue to be avoided + if (this->m_unit == otherQuantity.m_unit) { // same unit - if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) { + if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) { // pure integer comparison, no rounding issues - return this->_unitValueI == otherQuantity._unitValueI; + return this->m_unitValueI == otherQuantity.m_unitValueI; } else { - diff = abs(this->_unitValueD - otherQuantity._unitValueD); - return diff <= (lenient * this->_pUnit.getEpsilon()); + diff = abs(this->m_unitValueD - otherQuantity.m_unitValueD); + return diff <= (lenient * this->m_unit.getEpsilon()); } } else { // based on SI value - diff = abs(this->_convertedSiUnitValueD - otherQuantity._convertedSiUnitValueD); - return diff <= (lenient * this->_pUnit.getEpsilon()); + diff = abs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD); + return diff <= (lenient * this->m_unit.getEpsilon()); } } /** * Not equal */ -bool CPhysicalQuantity::operator !=(const CPhysicalQuantity &otherQuantity) const { +template bool CPhysicalQuantity::operator !=(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return false; return !(*this == otherQuantity); } @@ -96,37 +76,37 @@ bool CPhysicalQuantity::operator !=(const CPhysicalQuantity &otherQuantity) cons /** * Assigment operator = */ -CPhysicalQuantity& CPhysicalQuantity::operator=(const CPhysicalQuantity &otherQuantity) { +template CPhysicalQuantity& CPhysicalQuantity::operator=(const CPhysicalQuantity &otherQuantity) { // Check for self-assignment! if (this == &otherQuantity) return *this; // Same object? Yes, so skip assignment, and just return *this - CPhysicalQuantity::_unitValueI = otherQuantity._unitValueI; - CPhysicalQuantity::_unitValueD = otherQuantity._unitValueD; - CPhysicalQuantity::_convertedSiUnitValueD = otherQuantity._convertedSiUnitValueD; - CPhysicalQuantity::_isIntegerBaseValue = otherQuantity._isIntegerBaseValue; - CPhysicalQuantity::_pUnit = otherQuantity._pUnit; - CPhysicalQuantity::_pConversionSiUnit = otherQuantity._pConversionSiUnit; - CPhysicalQuantity::_unitConverter = otherQuantity._unitConverter; + this->m_unitValueI = otherQuantity.m_unitValueI; + this->m_unitValueD = otherQuantity.m_unitValueD; + this->m_convertedSiUnitValueD = otherQuantity.m_convertedSiUnitValueD; + this->m_isIntegerBaseValue = otherQuantity.m_isIntegerBaseValue; + this->m_unit = otherQuantity.m_unit; + this->m_conversionSiUnit = otherQuantity.m_conversionSiUnit; + this->m_unitConverter = otherQuantity.m_unitConverter; return *this; } /** * Plus operator */ -CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &otherQuantity) +template CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &otherQuantity) { - if (this->_pUnit == otherQuantity._pUnit) { + if (this->m_unit == otherQuantity.m_unit) { // same unit - if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) { + if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) { // pure integer, no rounding issues - this->setUnitValue(otherQuantity._unitValueI + this->_unitValueI); + this->setUnitValue(otherQuantity.m_unitValueI + this->m_unitValueI); } else { - this->setUnitValue(otherQuantity._unitValueI + this->_unitValueI); + this->setUnitValue(otherQuantity.m_unitValueD + this->m_unitValueD); } } else { - double v = otherQuantity.value(this->_pUnit); - this->setUnitValue(v + this->_unitValueD); + double v = otherQuantity.value(this->m_unit); + this->setUnitValue(v + this->m_unitValueD); } return *this; } @@ -134,40 +114,46 @@ CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &other /** * Plus operator */ -CPhysicalQuantity &CPhysicalQuantity::operator +=(double unprefixedSiUnitValue) +template PQ CPhysicalQuantity::operator +(const PQ &otherQuantity) const { - if (!this->isUnprefixedSiUnit()) { - this->switchUnit(this->_pConversionSiUnit); - } - this->setUnitValue(this->_unitValueD + unprefixedSiUnitValue); - return *this; + PQ plus(otherQuantity); + plus += (*this); + return plus; +} + + +/** + * Explicit plus + */ +template void CPhysicalQuantity::addUnitValue(double value) +{ + this->setUnitValue(this->m_unitValueD + value); } /** - * Plus operator + * Explicit minus */ -CPhysicalQuantity CPhysicalQuantity::operator +(const CPhysicalQuantity &otherQuantity) const +template void CPhysicalQuantity::substractUnitValue(double value) { - CPhysicalQuantity pq = (*this); - return pq+= otherQuantity; + this->setUnitValue(this->m_unitValueD - value); } /** * Minus operator */ -CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &otherQuantity) +template CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &otherQuantity) { - if (this->_pUnit == otherQuantity._pUnit) { + if (this->m_unit == otherQuantity.m_unit) { // same unit - if (this->_isIntegerBaseValue && otherQuantity._isIntegerBaseValue) { + if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) { // pure integer, no rounding issues - this->setUnitValue(otherQuantity._unitValueI - this->_unitValueI); + this->setUnitValue(otherQuantity.m_unitValueI - this->m_unitValueI); } else { - this->setUnitValue(otherQuantity._unitValueI - this->_unitValueI); + this->setUnitValue(otherQuantity.m_unitValueD - this->m_unitValueD); } } else { - double v = otherQuantity.value(this->_pUnit); - this->setUnitValue(v - this->_unitValueD); + double v = otherQuantity.value(this->m_unit); + this->setUnitValue(v - this->m_unitValueD); } return *this; } @@ -175,77 +161,83 @@ CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &other /** * Minus operator */ -CPhysicalQuantity &CPhysicalQuantity::operator -=(double unprefixedSiUnitValue) +template PQ CPhysicalQuantity::operator -(const PQ &otherQuantity) const { - *this += (-unprefixedSiUnitValue); - return *this; -} - -/** - * Minus operator - */ -CPhysicalQuantity CPhysicalQuantity::operator -(const CPhysicalQuantity &otherQuantity) const -{ - CPhysicalQuantity pq = (*this); - return pq-= otherQuantity; + PQ minus; + minus += (*this); + minus -= otherQuantity; + return minus; } /** * Multiply operator */ -CPhysicalQuantity &CPhysicalQuantity::operator *=(double multiply) +template CPhysicalQuantity &CPhysicalQuantity::operator *=(double multiply) { - this->setUnitValue(this->_unitValueD *multiply); + this->setUnitValue(this->m_unitValueD *multiply); return *this; } /** * Multiply operator */ -CPhysicalQuantity CPhysicalQuantity::operator *(double multiply) const +template PQ CPhysicalQuantity::operator *(double multiply) const { - CPhysicalQuantity pq= (*this); - return pq *= multiply; + PQ times; + times += (*this); + times *= multiply; + return times; } /** * Divide operator /= */ -CPhysicalQuantity &CPhysicalQuantity::operator /=(double divide) +template CPhysicalQuantity &CPhysicalQuantity::operator /=(double divide) { - this->setUnitValue(this->_unitValueD / divide); + this->setUnitValue(this->m_unitValueD / divide); return *this; } /** - * Divide operator /= + * Divide operator / */ -CPhysicalQuantity CPhysicalQuantity::operator /(double divide) const +template PQ CPhysicalQuantity::operator /(double divide) const { - CPhysicalQuantity pq= (*this); - return pq /= divide; + PQ div; + div += (*this); + div /= divide; + return div; } /** * Less operator < */ -bool CPhysicalQuantity::operator <(const CPhysicalQuantity &otherQuantity) const { +template bool CPhysicalQuantity::operator <(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return false; - double diff = this->_convertedSiUnitValueD - otherQuantity._convertedSiUnitValueD; - return (diff < 0 && abs(diff) >= this->_pUnit.getEpsilon()); + double diff = this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD; + return (diff < 0 && abs(diff) >= this->m_unit.getEpsilon()); } -bool CPhysicalQuantity::operator >(const CPhysicalQuantity &otherQuantity) const { +/** + * Greater than + */ +template bool CPhysicalQuantity::operator >(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return false; return otherQuantity < *this; } -bool CPhysicalQuantity::operator >=(const CPhysicalQuantity &otherQuantity) const { +/** + * Greater / Equal + */ +template bool CPhysicalQuantity::operator >=(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return true; return !(*this < otherQuantity); } -bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &otherQuantity) const { +/** + * Less equal + */ +template bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &otherQuantity) const { if(this == &otherQuantity) return true; return !(*this > otherQuantity); } @@ -253,12 +245,12 @@ bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &otherQuantity) cons /** * Switch to another unit */ -bool CPhysicalQuantity::switchUnit(const CMeasurementUnit &newUnit) +template bool CPhysicalQuantity::switchUnit(const MU &newUnit) { - if (this->_pUnit == newUnit) return true; - if (this->_pUnit.getType() != newUnit.getType()) return false; // not possible - double cf = this->_unitConverter(this, newUnit); - this->_pUnit = newUnit; + if (this->m_unit == newUnit) return true; + if (this->m_unit.getType() != newUnit.getType()) return false; // not possible + double cf = this->m_unitConverter(this, newUnit); + this->m_unit = newUnit; this->setUnitValue(cf); return true; } @@ -266,57 +258,57 @@ bool CPhysicalQuantity::switchUnit(const CMeasurementUnit &newUnit) /** * Init by integer */ -void CPhysicalQuantity::setUnitValue(qint32 baseValue) +template void CPhysicalQuantity::setUnitValue(qint32 baseValue) { - this->_unitValueI= baseValue; - this->_unitValueD= double(baseValue); - this->_isIntegerBaseValue = true; + this->m_unitValueI= baseValue; + this->m_unitValueD= double(baseValue); + this->m_isIntegerBaseValue = true; this->setConversionSiUnitValue(); } /** * Init by double */ -void CPhysicalQuantity::setUnitValue(double baseValue) +template void CPhysicalQuantity::setUnitValue(double baseValue) { - this->_unitValueD = baseValue; - this->_unitValueI = qRound(baseValue); - this->_isIntegerBaseValue = false; + this->m_unitValueD = baseValue; + this->m_unitValueI = qRound(baseValue); + this->m_isIntegerBaseValue = false; this->setConversionSiUnitValue(); } /** * Set SI value */ -void CPhysicalQuantity::setConversionSiUnitValue() { - this->_convertedSiUnitValueD = this->_unitConverter(this, this->_pConversionSiUnit); +template void CPhysicalQuantity::setConversionSiUnitValue() { + this->m_convertedSiUnitValueD = this->m_unitConverter(this, this->m_conversionSiUnit); } /** * Standard conversion by factor, used in most cases, in some cases (e.g. CTemperature) arbitrary converter */ -double CPhysicalQuantity::standardUnitFactorValueConverter(const CPhysicalQuantity *quantity, const CMeasurementUnit &otherUnit) { - if (quantity->_pUnit == CMeasurementUnit::None() || quantity->_unitValueD == 0.0) return 0.0; - if (quantity->_pUnit == otherUnit) return quantity->_unitValueD; - double f = quantity->_pUnit.conversionFactor(otherUnit); - return f * quantity->_unitValueD; +template double CPhysicalQuantity::standardUnitFactorValueConverter(const CPhysicalQuantity *quantity, const MU &otherUnit) { + if (quantity->m_unit == MU::None() || quantity->m_unitValueD == 0.0) return 0.0; + if (quantity->m_unit == otherUnit) return quantity->m_unitValueD; + double f = quantity->m_unit.conversionFactor(otherUnit); + return f * quantity->m_unitValueD; } /** * Round */ -double CPhysicalQuantity::unitValueToDoubleRounded(int digits) const +template double CPhysicalQuantity::unitValueToDoubleRounded(int digits) const { - if (digits < 1) digits = this->_pUnit.getDisplayDigits(); - return CPhysicalQuantity::round(this->_unitValueD, digits); + if (digits < 1) digits = this->m_unit.getDisplayDigits(); + return CPhysicalQuantity::round(this->m_unitValueD, digits); } /** * Rounded to QString */ -QString CPhysicalQuantity::toQStringRounded(double value, int digits) +template QString CPhysicalQuantity::toQStringRounded(double value, int digits) { - double v =CPhysicalQuantity::round(value, digits); + double v =CPhysicalQuantity::round(value, digits); QString s = QLocale::system().toString(v, 'f', digits); return s; } @@ -324,80 +316,80 @@ QString CPhysicalQuantity::toQStringRounded(double value, int digits) /** * Rounded value to QString */ -QString CPhysicalQuantity::unitValueToQStringRounded(int digits) const +template QString CPhysicalQuantity::unitValueToQStringRounded(int digits) const { - if (digits < 1) digits = this->_pUnit.getDisplayDigits(); - return CPhysicalQuantity::toQStringRounded(this->_unitValueD, digits); + if (digits < 1) digits = this->m_unit.getDisplayDigits(); + return CPhysicalQuantity::toQStringRounded(this->m_unitValueD, digits); } /** * Rounded SI value to QString */ -QString CPhysicalQuantity::convertedSiValueToQStringRounded(int digits) const +template QString CPhysicalQuantity::convertedSiValueToQStringRounded(int digits) const { - if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits(); - return CPhysicalQuantity::toQStringRounded(this->_convertedSiUnitValueD, digits); + if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits(); + return CPhysicalQuantity::toQStringRounded(this->m_convertedSiUnitValueD, digits); } /** * Value rounded in original unit */ -QString CPhysicalQuantity::unitValueRoundedWithUnit(int digits) const { - if (digits < 1) digits = this->_pUnit.getDisplayDigits(); - return this->unitValueToQStringRounded(digits).append(this->_pUnit.getUnitName()); +template QString CPhysicalQuantity::unitValueRoundedWithUnit(int digits) const { + if (digits < 1) digits = this->m_unit.getDisplayDigits(); + return this->unitValueToQStringRounded(digits).append(this->m_unit.getUnitName()); } /** * SI base unit value with unit */ -QString CPhysicalQuantity::convertedSiValueRoundedWithUnit(int digits) const { - if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits(); - return this->convertedSiValueToQStringRounded(digits).append(this->_pConversionSiUnit.getUnitName()); +template QString CPhysicalQuantity::convertedSiValueRoundedWithUnit(int digits) const { + if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits(); + return this->convertedSiValueToQStringRounded(digits).append(this->m_conversionSiUnit.getUnitName()); } /** * Value rounded in unit */ -QString CPhysicalQuantity::valueRoundedWithUnit(const CMeasurementUnit &unit, int digits) const +template QString CPhysicalQuantity::valueRoundedWithUnit(const MU &unit, int digits) const { - if (unit == this->_pUnit) return this->unitValueRoundedWithUnit(digits); - if (unit == this->_pConversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits); + if (unit == this->m_unit) return this->unitValueRoundedWithUnit(digits); + if (unit == this->m_conversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits); if (digits < 0) digits = unit.getDisplayDigits(); - return CPhysicalQuantity::toQStringRounded(this->value(unit), digits).append(unit.getUnitName()); + return CPhysicalQuantity::toQStringRounded(this->value(unit), digits).append(unit.getUnitName()); } /** * Value rounded in unit */ -double CPhysicalQuantity::valueRounded(const CMeasurementUnit &unit, int digits) const +template double CPhysicalQuantity::valueRounded(const MU &unit, int digits) const { if (digits < 1) digits = unit.getDisplayDigits(); - return CPhysicalQuantity::round(this->value(unit),digits); + return CPhysicalQuantity::round(this->value(unit),digits); } /** * Value in unit */ -double CPhysicalQuantity::value(const CMeasurementUnit &unit) const +template double CPhysicalQuantity::value(const MU &unit) const { - if (unit == this->_pConversionSiUnit) return this->_convertedSiUnitValueD; - double v = this->_unitConverter(this, unit); + if (unit == this->m_conversionSiUnit) return this->m_convertedSiUnitValueD; + double v = this->m_unitConverter(this, unit); return v; } /** * Round utility method */ -double CPhysicalQuantity::convertedSiValueToDoubleRounded(int digits) const +template double CPhysicalQuantity::convertedSiValueToDoubleRounded(int digits) const { - if (digits < 1) digits = this->_pConversionSiUnit.getDisplayDigits(); - return CPhysicalQuantity::round(this->_convertedSiUnitValueD, digits); + if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits(); + return CPhysicalQuantity::round(this->m_convertedSiUnitValueD, digits); } /** * Round utility method */ -double CPhysicalQuantity::round(double value, int digits) { +template double CPhysicalQuantity::round(double value, int digits) { // gosh, is there no Qt method for this??? // It's year 2013 double m = pow(10.0,digits); @@ -405,4 +397,14 @@ double CPhysicalQuantity::round(double value, int digits) { return rv; } -} // namespace BlackCore +// see here for the reason of this forward initialization +// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html +template class CPhysicalQuantity; +template class CPhysicalQuantity; +template class CPhysicalQuantity; +template class CPhysicalQuantity; +template class CPhysicalQuantity; +template class CPhysicalQuantity; +template class CPhysicalQuantity; + +} // namespace diff --git a/src/blackmisc/pqphysicalquantity.h b/src/blackmisc/pqphysicalquantity.h index 371878e14..bb2786a9d 100644 --- a/src/blackmisc/pqphysicalquantity.h +++ b/src/blackmisc/pqphysicalquantity.h @@ -1,65 +1,77 @@ #ifndef PQPHYSICALQUANTITY_H #define PQPHYSICALQUANTITY_H + #include #include #include #include "blackmisc/pqbase.h" +#include "blackmisc/pqunits.h" #include "blackmisc/debug.h" namespace BlackMisc { -class CPhysicalQuantity; - -/*! - * Our converter function, should be implemented as static method of the quantity - * classes for clarity - */ -typedef double (*CPhysicalQuantityUnitConverter)(const CPhysicalQuantity *quantity, const CMeasurementUnit &unit); +class CAngle; /*! * \brief A physical quantity such as "5m", "20s", "1500ft/s" * \author KWB */ -class CPhysicalQuantity +template class CPhysicalQuantity { + /*! + * Our converter function, should be implemented as static method of the quantity + * classes for clarity + */ + typedef double (*CPhysicalQuantityUnitConverter)(const CPhysicalQuantity *quantity, const MU &unit); + /*! * Stream operator for debugging * \brief operator << * \param debug * \param quantity * \return + * \remarks has to be in the header files toavoid templatelink errors */ - friend QDebug operator<<(QDebug debug, const CPhysicalQuantity &quantity); + friend QDebug operator<<(QDebug debug, const CPhysicalQuantity &quantity) { + QString v = quantity.unitValueRoundedWithUnit(-1); + debug << v; + return debug; + } + /*! * Stream operator for log messages * \brief operator << * \param log * \param quantity * \return + * \remarks has to be in the header files toavoid templatelink errors */ - friend CLogMessage operator<<(CLogMessage log, const CPhysicalQuantity &quantity); + friend CLogMessage operator<<(CLogMessage log, const CPhysicalQuantity &quantity) { + QString v = quantity.unitValueRoundedWithUnit(-1); + log << v; + return log; + } private: - qint32 _unitValueI; //!< value backed by integer, allows sole integer arithmetic - double _unitValueD; //!< value backed by double - double _convertedSiUnitValueD; //!< SI unit value - bool _isIntegerBaseValue; //!< flag integer? / double? - CPhysicalQuantityUnitConverter _unitConverter; //! *quantity, const MU &otherUnit); protected: - CMeasurementUnit _pUnit; //!< unit - CMeasurementUnit _pConversionSiUnit; //!< corresponding SI base unit + MU m_unit; //!< unit + MU m_conversionSiUnit; //!< corresponding SI base unit /*! * \brief Constructor with int @@ -68,7 +80,7 @@ protected: * \param siBaseUnit * \param unitConverter */ - CPhysicalQuantity(qint32 baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, + CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter = CPhysicalQuantity::standardUnitFactorValueConverter); /*! * \brief Constructor with double @@ -76,7 +88,7 @@ protected: * \param unit * \param siBaseUnit */ - CPhysicalQuantity(double baseValue, const CMeasurementUnit &unit, const CMeasurementUnit &siConversionUnit, + CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter = CPhysicalQuantity::standardUnitFactorValueConverter); /*! * \brief Init by integer @@ -93,39 +105,47 @@ protected: * \brief Set the SI value */ void setConversionSiUnitValue(); - public: /*! * \brief Copy constructor * \param otherQuantity */ - CPhysicalQuantity(const CPhysicalQuantity &otherQuantity); + CPhysicalQuantity(const CPhysicalQuantity &otherQuantity); /*! * \brief Virtual destructor */ - virtual ~CPhysicalQuantity(); - + virtual ~CPhysicalQuantity(); + /*! + * \brief Unit of the distance + * \return + */ + MU getUnit() const { return this->m_unit; } + /*! + * \brief Conversion SI unit + * \return + */ + MU getConversionSiUnit() const { return this->m_conversionSiUnit; } /*! * \brief Switch unit, e.g. feet meter * \param newUnit * \return */ - bool switchUnit(const CMeasurementUnit &newUnit); + bool switchUnit(const MU &newUnit); /*! * \brief Value in SI base unit? Meter is an SI base unit, hertz not! * \return */ - bool isSiBaseUnit() const { return this->_pUnit.isSiBaseUnit(); } + bool isSiBaseUnit() const { return this->m_unit.isSiBaseUnit(); } /*! * \brief Value in SI unit? Hertz is an derived SI unit, NM not! * \return */ - bool isSiUnit() const { return this->_pUnit.isSiUnit(); } + bool isSiUnit() const { return this->m_unit.isSiUnit(); } /*! * \brief Value in unprefixed SI unit? Meter is a unprefixed, kilometer a prefixed SI Unit * \return */ - bool isUnprefixedSiUnit() const { return this->_pUnit.isUnprefixedSiUnit(); } + bool isUnprefixedSiUnit() const { return this->m_unit.isUnprefixedSiUnit(); } /*! * \brief Value to QString with unit, e.g. "5.00m" * \param digits @@ -137,41 +157,41 @@ public: * \param unit * @return */ - double value(const CMeasurementUnit &unit) const; + double value(const MU &unit) const; /*! * \brief Rounded value in unit * \param unit * \param digits * @return */ - double valueRounded(const CMeasurementUnit &unit, int digits = -1) const; + double valueRounded(const MU &unit, int digits = -1) const; /*! * \brief Value to QString with unit, e.g. "5.00m" * \param unit * \param digits * @return */ - QString valueRoundedWithUnit(const CMeasurementUnit &unit, int digits = -1) const; + QString valueRoundedWithUnit(const MU &unit, int digits = -1) const; /*! * \brief Value a int * @return */ - qint32 unitValueToInteger() const { return this->_unitValueI;} + qint32 unitValueToInteger() const { return this->m_unitValueI;} /*! * \brief Value a double * @return */ - double unitValueToDouble() const { return this->_unitValueD;} + double unitValueToDouble() const { return this->m_unitValueD;} /*! * \brief SI value to integer * @return */ - qint32 siBaseUnitValueToInteger() const { return CPhysicalQuantity::round(this->_convertedSiUnitValueD,0);} + qint32 siBaseUnitValueToInteger() const { return CPhysicalQuantity::round(this->m_convertedSiUnitValueD,0);} /*! * \brief SI value to double * @return */ - double siBaseUnitValueToDouble() const { return this->_convertedSiUnitValueD;} + double siBaseUnitValueToDouble() const { return this->m_convertedSiUnitValueD;} /*! * \brief Rounded value by n digits * \param digits @@ -188,12 +208,12 @@ public: * \brief SI value as double * \return */ - double convertedSiValueToDouble() const { return this->_convertedSiUnitValueD;} + double convertedSiValueToDouble() const { return this->m_convertedSiUnitValueD;} /*! * \brief SI value as integer * \return */ - qint32 convertedSiValueToInteger() const { return (qint32)CPhysicalQuantity::round(this->_convertedSiUnitValueD,0);} + qint32 convertedSiValueToInteger() const { return (qint32)CPhysicalQuantity::round(this->m_convertedSiUnitValueD,0);} /*! * \brief Rounded SI value by n digits * \param digits @@ -212,116 +232,118 @@ public: * @return */ QString convertedSiValueRoundedWithUnit(int digits = -1) const; + /*! + * \brief Add to the unit value. + * \remarks Since overloading the + operator with double did lead to unintended conversions, as explicit method + * \param value + */ + void addUnitValue(double value); + /*! + * \brief Substratc to the unit value. + * \remarks Since overloading the - operator with double did lead to unintended conversions, as explicit method + * \param value + */ + void substractUnitValue(double value); /*! * \brief Cast as double */ - operator double() const { return this->_convertedSiUnitValueD; } + operator double() const { return this->m_convertedSiUnitValueD; } /*! * \brief Cast as QString */ operator QString() const { return this->unitValueRoundedWithUnit();} - /*! - * \brief Assignment operator = - * \param otherQuantity - * @return - */ - CPhysicalQuantity &operator =(const CPhysicalQuantity &otherQuantity); - /*! - * \brief Plus operator += - * \param otherQuantity - * @return - */ - CPhysicalQuantity &operator +=(const CPhysicalQuantity &otherQuantity); - /*! - * \brief Plus operator += - * \param unprefixedSiUnitValue - * @return - */ - CPhysicalQuantity &operator +=(double unprefixedSiUnitValue); - /*! - * \brief Minus operator-= - * \param otherQuantity - * @return - */ - CPhysicalQuantity &operator -=(const CPhysicalQuantity &otherQuantity); - /*! - * \brief Plus operator += - * \param unprefixedSiUnitValue - * @return - */ - CPhysicalQuantity &operator -=(double unprefixedSiUnitValue); - /*! - * \brief Plus operator + - * \param otherQuantity - * @return - */ - CPhysicalQuantity operator +(const CPhysicalQuantity &otherQuantity) const; - /*! - * \brief Minus operator - - * \param otherQuantity - * @return - */ - CPhysicalQuantity operator -(const CPhysicalQuantity &otherQuantity) const; + /*! * \brief Multiply operator *= * \param multiply - * @return + * \return */ - CPhysicalQuantity &operator *=(double multiply); + CPhysicalQuantity &operator *=(double multiply); /*! * \brief Divide operator /= * \param divide * @return */ - CPhysicalQuantity &operator /=(double divide); + CPhysicalQuantity &operator /=(double divide); /*! * \brief Operator * * \param multiply * @return */ - CPhysicalQuantity operator *(double multiply) const; + PQ operator *(double multiply) const; /*! * \brief Operator / * \param divide * @return */ - CPhysicalQuantity operator /(double divide) const; + PQ operator /(double divide) const; /*! * \brief Equal operator == * \param otherQuantity * @return */ - bool operator==(const CPhysicalQuantity &otherQuantity) const; + bool operator==(const CPhysicalQuantity &otherQuantity) const; /*! * \brief Not equal operator != * \param otherQuantity * @return */ - bool operator!=(const CPhysicalQuantity &otherQuantity) const; + bool operator!=(const CPhysicalQuantity &otherQuantity) const; + /*! + * \brief Plus operator += + * \param otherQuantity + * @return + */ + CPhysicalQuantity &operator +=(const CPhysicalQuantity &otherQuantity); + /*! + * \brief Minus operator-= + * \param otherQuantity + * @return + */ + CPhysicalQuantity &operator -=(const CPhysicalQuantity &otherQuantity); /*! * \brief Greater operator > * \param otherQuantity * @return */ - bool operator >(const CPhysicalQuantity &otherQuantity) const; + bool operator >(const CPhysicalQuantity &otherQuantity) const; /*! * \brief Less operator < * \param otherQuantity * @return */ - bool operator <(const CPhysicalQuantity &otherQuantity) const; + bool operator <(const CPhysicalQuantity &otherQuantity) const; /*! * \brief Less equal operator <= * \param otherQuantity * @return */ - bool operator <=(const CPhysicalQuantity &otherQuantity) const; + bool operator <=(const CPhysicalQuantity &otherQuantity) const; /*! * \brief Greater equal operator >= * \param otherQuantity * @return */ - bool operator >=(const CPhysicalQuantity &otherQuantity) const; + bool operator >=(const CPhysicalQuantity &otherQuantity) const; + /*! + * \brief Assignment operator = + * \param otherQuantity + * @return + */ + CPhysicalQuantity &operator =(const CPhysicalQuantity &otherQuantity); + /*! + * \brief Plus operator + + * \param otherQuantity + * @return + */ + PQ operator +(const PQ &otherQuantity) const; + /*! + * \brief Minus operator - + * \param otherQuantity + * @return + */ + PQ operator -(const PQ &otherQuantity) const; + // -------------------------------------------------------------------- // -- static @@ -343,5 +365,7 @@ public: */ static QString toQStringRounded(double value, int digits); }; + } // namespace BlackCore + #endif // PQPHYSICALQUANTITY_H diff --git a/src/blackmisc/pqpressure.cpp b/src/blackmisc/pqpressure.cpp deleted file mode 100644 index cfa4877df..000000000 --- a/src/blackmisc/pqpressure.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "blackmisc/pqpressure.h" - -namespace BlackMisc { - -/** - * Default constructor - */ -CPressure::CPressure() : CPhysicalQuantity(0, CPressureUnit::Pa(), CPressureUnit::Pa()) -{ - // void -} - -/** - * Constructor - */ -CPressure::CPressure(const CPhysicalQuantity &pressure): CPhysicalQuantity(pressure) -{ - //void -} - -/** - * Constructor - */ -CPressure::CPressure(qint32 value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit, CPressureUnit::Pa()) -{ - // void -} - -/** - * Constructor - */ -CPressure::CPressure(double value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit, CPressureUnit::Pa()) -{ - // void -} - -/** - * Destructor - */ -CPressure::~CPressure() -{ - // void -} - - -} // namespace diff --git a/src/blackmisc/pqpressure.h b/src/blackmisc/pqpressure.h index a88fb0432..f64568f99 100644 --- a/src/blackmisc/pqpressure.h +++ b/src/blackmisc/pqpressure.h @@ -5,111 +5,37 @@ namespace BlackMisc { -/*! - * Specialized class for pressure (psi, hPa, bar). - * \author KWB - */ -class CPressureUnit : public CMeasurementUnit { - friend class CPressure; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * and cast unit - * \param otherUnit - */ - CPressureUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief Pressure unit - * \param name - * \param unitName - * \param isSIUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CPressureUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "frequency", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Pascal - * \return - */ - static const CPressureUnit& Pa() { static CPressureUnit Pa("pascal", "Pa", true); return Pa;} - /*! - * \brief Hectopascal - * \return - */ - static const CPressureUnit& hPa() { static CPressureUnit hPa("hectopascal", "hPa", true, CMeasurementPrefix::h().getFactor(), CMeasurementPrefix::h()); return hPa;} - /*! - * \brief Pounds per square inch - * \return - */ - static const CPressureUnit& psi() { static CPressureUnit psi("pounds per square inch", "psi", false, 6894.8, CMeasurementPrefix::One(), 2); return psi;} - /*! - * \brief Bar - * \return - */ - static const CPressureUnit& bar() { static CPressureUnit bar("bar", "bar", false, 1E5);return bar;} - /*! - * \brief Millibar, actually the same as hPa - * \return - */ - static const CPressureUnit& mbar() { static CPressureUnit bar("bar", "bar", false, 1E2);return bar;} - /*! - * \brief Inch of mercury at 0°C - * \return - */ - static const CPressureUnit& inHg() { static CPressureUnit inhg("Inch of mercury 0°C", "inHg", false, 3386.389);return inhg;} - /*! - * \brief Inch of mercury for flight level 29,92inHg = 1013,25mbar = 1013,25hPa - * \return - */ - static const CPressureUnit& inHgFL() { static CPressureUnit inhg("Inch of mercury ", "inHg", false, 3386.5307486631);return inhg;} -}; - /*! * \brief Physical unit distance * \author KWB */ -class CPressure : public CPhysicalQuantity +class CPressure : public CPhysicalQuantity { public: /*! * \brief Default constructor */ - CPressure(); + CPressure() : CPhysicalQuantity(0, CPressureUnit::Pa(), CPressureUnit::Pa()){} /** - *\brief downcast copy constructor + *\brief Copy constructor */ - CPressure(const CPhysicalQuantity &frequency); + CPressure(const CPressure &pressure) : CPhysicalQuantity(pressure) {} /*! * \brief Init by int value * \param value * \param unit */ - CPressure(qint32 value, const CPressureUnit &unit = CPressureUnit::Pa()); + CPressure(qint32 value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit, CPressureUnit::Pa()){} /*! *\brief Init by double value * \param value * \param unit */ - CPressure(double value, const CPressureUnit &unit = CPressureUnit::Pa()); + CPressure(double value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit, CPressureUnit::Pa()){} /*! * \brief Virtual destructor */ - virtual ~CPressure(); - /*! - * \brief Unit of the distance - * \return - */ - CPressureUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CPressureUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CPressure() {} }; -} // namespace blackCore +} // namespace #endif // PQPRESSURE_H diff --git a/src/blackmisc/pqspeed.cpp b/src/blackmisc/pqspeed.cpp deleted file mode 100644 index 51b413ccf..000000000 --- a/src/blackmisc/pqspeed.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "blackmisc/pqspeed.h" - -namespace BlackMisc { - -/** - * Default constructor - */ -CSpeed::CSpeed() : CPhysicalQuantity(0, CSpeedUnit::m_s(), CSpeedUnit::m_s()) -{ - // void -} - -///** -// * Constructor -// */ -//CSpeed::CSpeed(const CPhysicalQuantity &speed): CPhysicalQuantity(speed) -//{ -// //void -//} - -/** - * Constructor - */ -CSpeed::CSpeed(qint32 value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit, CSpeedUnit::m_s()) -{ - // void -} - -/** - * Constructor - */ -CSpeed::CSpeed(double value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit, CSpeedUnit::m_s()) -{ - // void -} - -/*! - * \brief Destructor - */ -CSpeed::~CSpeed() -{ - // void -} - -} // namespace diff --git a/src/blackmisc/pqspeed.h b/src/blackmisc/pqspeed.h index b313c5aac..da4f9d56a 100644 --- a/src/blackmisc/pqspeed.h +++ b/src/blackmisc/pqspeed.h @@ -4,101 +4,37 @@ namespace BlackMisc { -/*! - * Specialized class for speed units (m/s, ft/s, NM/h). - * \author KWB - */ -class CSpeedUnit : public CMeasurementUnit { -public: - /*! - * Constructor - * \brief CSpeedUnit - * \param name - * \param unitName - * \param isSIUnit - * \param isSIBaseUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CSpeedUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "speed", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CSpeedUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} - /*! - * \brief Meter/second m/s - * \return - */ - static const CSpeedUnit& m_s() { static CSpeedUnit ms("meter/second", "m/s", true, false); return ms;} - /*! - * \brief Nautical miles per hour NM/h - * \return - */ - static const CSpeedUnit& NM_h() { static CSpeedUnit NMh("nautical miles/hour", "NM/h", false, false, 1852.0/3600.0, CMeasurementPrefix::One(), 1);return NMh;} - /*! - * \brief Feet/second ft/s - * \return - */ - static const CSpeedUnit& ft_s() { static CSpeedUnit fts("feet/seconds", "ft/s", false, false, 0.3048, CMeasurementPrefix::One(), 0); return fts;} - /*! - * \brief Feet/min ft/min - * \return - */ - static const CSpeedUnit& ft_min() { static CSpeedUnit ftmin("feet/minute", "ft/min", false, false, 0.3048 / 60.0, CMeasurementPrefix::One(), 0); return ftmin;} - /*! - * \brief Kilometer/hour km/h - * \return - */ - static const CSpeedUnit& km_h() { static CSpeedUnit kmh("kilometer/hour", "km/h", false, false, 1.0/3.6, CMeasurementPrefix::One(), 1);return kmh;} -}; - /*! * Speed class, e.g. "m/s", "NM/h", "km/h", "ft/s" * \author KWB */ -class CSpeed : public CPhysicalQuantity +class CSpeed : public CPhysicalQuantity { - friend class CSpeedUnit; -private: - /** - *\brief Downcast copy constructor, allows casting units - */ - CSpeed(const CPhysicalQuantity &speed); public: /*! * \brief Default constructor */ - CSpeed(); + CSpeed() : CPhysicalQuantity(0, CSpeedUnit::m_s(), CSpeedUnit::m_s()) {} + /** + *\brief Copy constructor + */ + CSpeed(const CPhysicalQuantity &speed): CPhysicalQuantity(speed) {} /*! * \brief Init by int value * \param value * \param unit */ - CSpeed(qint32 value, const CSpeedUnit &unit = CSpeedUnit::m_s()); + CSpeed(qint32 value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit, CSpeedUnit::m_s()) {} /*! *\brief Init by double value * \param value * \param unit */ - CSpeed(double value, const CSpeedUnit &unit = CSpeedUnit::m_s()); + CSpeed(double value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit, CSpeedUnit::m_s()) {} /*! * \brief Destructor */ - virtual ~CSpeed(); - /*! - * \brief Unit of the distance - * \return - */ - CSpeedUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CSpeedUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CSpeed() {} }; } // namespace diff --git a/src/blackmisc/pqtemperature.cpp b/src/blackmisc/pqtemperature.cpp index 303bb3d90..9cb52d57d 100644 --- a/src/blackmisc/pqtemperature.cpp +++ b/src/blackmisc/pqtemperature.cpp @@ -2,61 +2,21 @@ namespace BlackMisc { -/** - * Default Constructor - */ -CTemperature::CTemperature(): CPhysicalQuantity(0, CTemperatureUnit::K(),CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) -{ - // void -} - -/** - * Constructor - */ -CTemperature::CTemperature(const CPhysicalQuantity &temperature): CPhysicalQuantity(temperature) -{ - // void -} - -/** - * Constructor - */ -CTemperature::CTemperature(qint32 value, const CTemperatureUnit &unit) : CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) -{ - // void -} - -/** - * Constructor - */ -CTemperature::CTemperature(double value, const CTemperatureUnit &unit) : CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) -{ - // void -} - -/** - * Destructor - */ -CTemperature::~CTemperature() -{ - // void -} - /** * Specialized method for temperture */ -double CTemperature::temperaturUnitConverter(const CPhysicalQuantity *quantity, const CMeasurementUnit &otherUnit) +double CTemperature::temperaturUnitConverter(const CPhysicalQuantity *quantity, const CTemperatureUnit &otherUnit) { CTemperature *me = (CTemperature*) quantity; // allow me access to protected - if (me->_pUnit == otherUnit) return me->siBaseUnitValueToDouble(); + if (me->m_unit == otherUnit) return me->siBaseUnitValueToDouble(); double siValue; // I always convert via SI Unit, other I would need too many conversions - if(otherUnit == me->_pConversionSiUnit) { + if(otherUnit == me->m_conversionSiUnit) { // here I expect a conversion to SI is required and not done yet - if(me->_pUnit == CTemperatureUnit::C()) { + if(me->m_unit == CTemperatureUnit::C()) { siValue = quantity->unitValueToDouble() + 273.15; - } else if(me->_pUnit == CTemperatureUnit::F()) { + } else if(me->m_unit == CTemperatureUnit::F()) { siValue = (me->unitValueToDouble() + 459.67) *5.0 / 9.0; } else{ // TODO: EXCEPTION @@ -67,14 +27,14 @@ double CTemperature::temperaturUnitConverter(const CPhysicalQuantity *quantity, } // from SI - if (otherUnit == me->_pConversionSiUnit) return siValue; + if (otherUnit == me->m_conversionSiUnit) return siValue; if(otherUnit == CTemperatureUnit::C()) { return siValue - 273.15; - } else if(me->_pUnit == CTemperatureUnit::F()) { + } else if(me->m_unit == CTemperatureUnit::F()) { return (siValue * 9.0 / 5.0) - 459.67; } // TODO: Exception return 0; } -} // namespace BlackCore +} // namespace diff --git a/src/blackmisc/pqtemperature.h b/src/blackmisc/pqtemperature.h index c830ad96d..027032f0d 100644 --- a/src/blackmisc/pqtemperature.h +++ b/src/blackmisc/pqtemperature.h @@ -4,55 +4,11 @@ namespace BlackMisc { -/*! - * Specialized class for temperatur units (kelvin, centidegree). - * \author KWB - */ -class CTemperatureUnit : public CMeasurementUnit { - friend class CTemperature; -private: - /*! - * Downcast copy constructor, allows to implement methods in base class - * \param otherUnit - */ - CTemperatureUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {} -public: - /*! - * Constructor - * \brief Temperature unit - * \param name - * \param unitName - * \param isSIUnit - * \param isSIBaseUnit - * \param conversionFactorToSI - * \param mulitplier - * \param displayDigits - * \param epsilon - */ - CTemperatureUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : - CMeasurementUnit(name, unitName, "temperature", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} - /*! - * \brief Kelvin - * \return - */ - static const CTemperatureUnit& K() { static CTemperatureUnit K("Kelvin", "K", true, true); return K;} - /*! - * \brief Centigrade C - * \return - */ - static const CTemperatureUnit& C() { static CTemperatureUnit C("centigrade", "°C", false, false);return C;} - /*! - * \brief Fahrenheit F - * \return - */ - static const CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0);return F;} -}; - /*! * \brief Physical unit temperature * \author KWB */ -class CTemperature : public CPhysicalQuantity +class CTemperature : public CPhysicalQuantity { private: /*! @@ -61,42 +17,33 @@ private: * \param otherUnit * \return */ - static double temperaturUnitConverter(const CPhysicalQuantity *quantity, const CMeasurementUnit &otherUnit); + static double temperaturUnitConverter(const CPhysicalQuantity *quantity, const CTemperatureUnit &otherUnit); + public: /*! * \brief Default constructor */ - CTemperature(); + CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::K(), CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} /** - *\brief downcast copy constructor + *\brief Copy constructor */ - CTemperature(const CPhysicalQuantity &temperature); + CTemperature(const CTemperature &temperature) : CPhysicalQuantity(temperature){} /*! * \brief Init by int value * \param value * \param unit */ - CTemperature(qint32 value, const CTemperatureUnit &unit = CTemperatureUnit::K()); + CTemperature(qint32 value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} /*! *\brief Init by double value * \param value * \param unit */ - CTemperature(double value, const CTemperatureUnit &unit = CTemperatureUnit::K()); + CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} /*! * \brief Destructor */ - virtual ~CTemperature(); - /*! - * \brief Unit of the temperature - * \return - */ - CTemperatureUnit getUnit() const { return this->_pUnit; } - /*! - * \brief Conversion SI unit - * \return - */ - CTemperatureUnit getConversionSiUnit() const { return this->_pConversionSiUnit; } + virtual ~CTemperature() {} }; } // namespace diff --git a/tests/blackmisc/testphysicalquantitiesbase.cpp b/tests/blackmisc/testphysicalquantitiesbase.cpp index debce3356..ae7a1f2e1 100644 --- a/tests/blackmisc/testphysicalquantitiesbase.cpp +++ b/tests/blackmisc/testphysicalquantitiesbase.cpp @@ -37,9 +37,9 @@ void TestPhysicalQuantitiesBase::unitsBasics() */ void TestPhysicalQuantitiesBase::distanceBasics() { - CDistance d1(1); // 1m + CDistance d1(1,CDistanceUnit::m()); // 1m CDistance d2(100, CDistanceUnit::cm()); - CDistance d3(1.852 * 1000); // 1852m + CDistance d3(1.852 * 1000,CDistanceUnit::m()); // 1852m CDistance d4(1,CDistanceUnit::NM()); QVERIFY2(d1 == d2, "1meter shall be 100cm"); @@ -54,11 +54,11 @@ void TestPhysicalQuantitiesBase::distanceBasics() QVERIFY2(!(d1 > d2), "Nothing shall be less / greater"); // epsilon tests - d1 += d1.getUnit().getEpsilon(); // this should be still the same + d1.addUnitValue(d1.getUnit().getEpsilon()); // this should be still the same QVERIFY2(d1 == d2, "Epsilon: 1meter+epsilon shall be 100cm"); QVERIFY2(!(d1 != d2), "Epsilon: 1meter+epsilon shall be 100cm"); - d1 += d1.getUnit().getEpsilon(); // now over epsilon threshold + d1.addUnitValue(d1.getUnit().getEpsilon()); // now over epsilon threshold QVERIFY2(d1 != d2, "Epsilon exceeded: 1meter+2epsilon shall not be 100cm"); QVERIFY2(d1 > d2, "d1 shall be greater"); } @@ -82,7 +82,7 @@ void TestPhysicalQuantitiesBase::frequencyTests() CFrequency f1(1, CFrequencyUnit::MHz()); QVERIFY2(f1.valueRounded(CFrequencyUnit::kHz(),2) == 1000, "Mega is 1000kHz"); QVERIFY2(f1 == 1000000 , "MHz is 1E6 Hz"); - CFrequency f2 = CMeasurementPrefix::M(); // 1 Megahertz + CFrequency f2(CMeasurementPrefix::M(),CFrequencyUnit::Hz()) ; // 1 Megahertz QVERIFY2(f1 == f2 , "MHz is 1E6 Hz"); } @@ -92,7 +92,7 @@ void TestPhysicalQuantitiesBase::frequencyTests() void TestPhysicalQuantitiesBase::angleTests() { CAngle a1(180, CAngleUnit::deg()); - CAngle a2(1.5 * CAngle::pi()); + CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad()); a2.switchUnit(CAngleUnit::deg()); QVERIFY2(a2.unitValueToInteger() == 270, qPrintable(QString("1.5Pi should be 270deg, not %1 deg").arg(a2.unitValueToInteger()))); QVERIFY2(a1.piFactor() == 1, qPrintable(QString("Pi should be 1PI,not %1").arg(a1.piFactor()))); @@ -103,8 +103,8 @@ void TestPhysicalQuantitiesBase::angleTests() */ void TestPhysicalQuantitiesBase::massTests() { - CMass w1(1000); - CMass w2(w1); + CMass w1(1000, CMassUnit::kg()); + CMass w2(w1, CMassUnit::kg()); w2.switchUnit(CMassUnit::t()); QVERIFY2(w2.unitValueToInteger() == 1, "1tonne shall be 1000kg"); w2.switchUnit(CMassUnit::lb()); @@ -140,25 +140,41 @@ void TestPhysicalQuantitiesBase::temperatureTests() QVERIFY2(t1.convertedSiValueToDoubleRounded() == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.convertedSiValueToDoubleRounded()))); QVERIFY2(t2.valueRounded(CTemperatureUnit::C()) == -17.22, qPrintable(QString("1F shall be -17.22C, not %1 C").arg(t2.valueRounded(CTemperatureUnit::C())))); QVERIFY2(t3.valueRounded(CTemperatureUnit::C()) == 104.53, qPrintable(QString("220.15F shall be 104.53C, not %1 C").arg(t3.valueRounded(CTemperatureUnit::C())))); - } /** - * @brief Just tesing obvious memory create / destruct flaws + * @brief Just testing obvious memory create / destruct flaws */ void TestPhysicalQuantitiesBase::memoryTests() { - CDistance* c = new CDistance(100); + CDistance* c = new CDistance(100, CDistanceUnit::m()); c->switchUnit(CDistanceUnit::NM()); QVERIFY2(c->getUnit() == CDistanceUnit::NM() && c->getConversionSiUnit() == CDistanceUnit::m(), "Testing distance units failed"); delete c; - CAngle* a = new CAngle(100); + CAngle* a = new CAngle(100, CAngleUnit::rad()); a->switchUnit(CAngleUnit::deg()); QVERIFY2(a->getUnit() == CAngleUnit::deg() && c->getConversionSiUnit() == CAngleUnit::rad(), "Testing angle units failed"); delete a; } +/** + * @brief Just testing obvious memory create / destruct flaws + */ +void TestPhysicalQuantitiesBase::basicArithmetic() +{ + CPressure p1 = CPhysicalQuantitiesConstants::InternationalStandardSeaLevelPressure(); + CPressure p2(p1); + p2 *= 2.0; + CPressure p3 = p1 + p1; + QVERIFY2(p3 == p2, "Pressure needs to be the same (2times)"); + p3 /= 2.0; + QVERIFY2(p3 == p1, "Pressure needs to be the same (1time)"); + p3 = p3 - p3; + QVERIFY2(p3.unitValueToDouble() == 0, "Value needs to be zero"); +} + + } // namespace diff --git a/tests/blackmisc/testphysicalquantitiesbase.h b/tests/blackmisc/testphysicalquantitiesbase.h index 09e6cbd65..1e59bf34d 100644 --- a/tests/blackmisc/testphysicalquantitiesbase.h +++ b/tests/blackmisc/testphysicalquantitiesbase.h @@ -53,9 +53,14 @@ private slots: */ void temperatureTests(); /*! - * \brief testing construction / destruction in memory + * \brief Testing construction / destruction in memory */ void memoryTests(); + /*! + * \brief Basic arithmetic such as +/- + */ + void basicArithmetic(); + }; }