From 8b1ef4345d86efaeccfc72df955e742b23353516 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Tue, 18 Feb 2014 18:36:49 +0000 Subject: [PATCH] refs #126 null unit infrastructure, a sentinel to mark an uninitialized or unused physical quantity --- src/blackmisc/pqbase.cpp | 3 +- src/blackmisc/pqbase.h | 16 ++++ src/blackmisc/pqphysicalquantity.h | 8 ++ src/blackmisc/pqunits.h | 126 +++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) diff --git a/src/blackmisc/pqbase.cpp b/src/blackmisc/pqbase.cpp index c9aac01ad..597cbcaa2 100644 --- a/src/blackmisc/pqbase.cpp +++ b/src/blackmisc/pqbase.cpp @@ -39,8 +39,7 @@ namespace BlackMisc */ double CMeasurementUnit::convertFrom(double value, const CMeasurementUnit &unit) const { - Q_ASSERT(this->m_converter); - Q_ASSERT(unit.m_converter); + if (this->isNull() || unit.isNull()) return -1; // models the previous behaviour of using -1 as a sentinel value if (this->m_converter == unit.m_converter) return value; return this->m_converter->fromDefault(unit.m_converter->toDefault(value)); } diff --git a/src/blackmisc/pqbase.h b/src/blackmisc/pqbase.h index 0216a44d2..a45720bae 100644 --- a/src/blackmisc/pqbase.h +++ b/src/blackmisc/pqbase.h @@ -16,6 +16,7 @@ #include #include #include +#include namespace BlackMisc { @@ -214,6 +215,13 @@ namespace BlackMisc : m_name(name), m_symbol(symbol), m_epsilon(epsilon), m_displayDigits(displayDigits), m_converter(new Converter) {} + /*! + * Construct a null unit + */ + CMeasurementUnit(const QString &name, const QString &symbol, std::nullptr_t) + : m_name(name), m_symbol(symbol), m_epsilon(0.0), m_displayDigits(0) + {} + //! \copydoc CValueObject::stringForStreaming virtual QString stringForStreaming() const override { @@ -348,6 +356,14 @@ namespace BlackMisc return abs(value) <= this->m_epsilon; } + /*! + * \brief Is unit null? + */ + bool isNull() const + { + return this->m_converter.data() == nullptr; + } + // -------------------------------------------------------------------- // -- static // -------------------------------------------------------------------- diff --git a/src/blackmisc/pqphysicalquantity.h b/src/blackmisc/pqphysicalquantity.h index 606655c26..e1f5e1750 100644 --- a/src/blackmisc/pqphysicalquantity.h +++ b/src/blackmisc/pqphysicalquantity.h @@ -125,6 +125,14 @@ namespace BlackMisc */ PQ &switchUnit(const MU &newUnit); + /*! + * Is quantity null? + */ + bool isNull() const + { + return this->m_unit.isNull(); + } + /*! * \brief Value in given unit */ diff --git a/src/blackmisc/pqunits.h b/src/blackmisc/pqunits.h index f4bb769fd..7829870bd 100644 --- a/src/blackmisc/pqunits.h +++ b/src/blackmisc/pqunits.h @@ -37,6 +37,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CLengthUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + struct NauticalMilesToMeters { static double factor() { return 1852.0; } }; struct FeetToMeters { static double factor() { return 0.3048; } }; struct MilesToMeters { static double factor() { return 1609.344; } }; @@ -62,6 +66,15 @@ namespace BlackMisc */ static const CLengthUnit &defaultUnit() { return m(); } + /*! + * \brief Null unit + */ + static const CLengthUnit &nullUnit() + { + static CLengthUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Meter m */ @@ -133,6 +146,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CLengthUnit::nullUnit()); u.append(CLengthUnit::cm()); u.append(CLengthUnit::ft()); u.append(CLengthUnit::km()); @@ -167,6 +181,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CAngleUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + struct RadiansToDegrees { static double factor() { return 180.0 / M_PI; } }; typedef One DegreesToDegrees; @@ -189,6 +207,15 @@ namespace BlackMisc */ static const CAngleUnit &defaultUnit() { return deg(); } + /*! + * \brief Null unit + */ + static const CAngleUnit &nullUnit() + { + static CAngleUnit nu("null", "null", nullptr); + return nu; + } + /*! * \copydoc CMeasurementUnit::makeRoundedQStringWithUnit */ @@ -242,6 +269,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CAngleUnit::nullUnit()); u.append(CAngleUnit::deg()); u.append(CAngleUnit::rad()); u.append(CAngleUnit::sexagesimalDeg()); @@ -273,6 +301,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CFrequencyUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + typedef One HertzToHertz; public: @@ -294,6 +326,15 @@ namespace BlackMisc */ static const CFrequencyUnit &defaultUnit() { return Hz(); } + /*! + * \brief Null unit + */ + static const CFrequencyUnit &nullUnit() + { + static CFrequencyUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Hertz */ @@ -338,6 +379,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CFrequencyUnit::nullUnit()); u.append(CFrequencyUnit::GHz()); u.append(CFrequencyUnit::Hz()); u.append(CFrequencyUnit::kHz()); @@ -369,6 +411,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CMassUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + typedef Milli GramsToKilograms; struct PoundsToKilograms { static double factor() { return 0.45359237; } }; @@ -391,6 +437,15 @@ namespace BlackMisc */ static const CMassUnit &defaultUnit() { return kg(); } + /*! + * \brief Null unit + */ + static const CMassUnit &nullUnit() + { + static CMassUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Kilogram, SI base unit */ @@ -444,6 +499,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CMassUnit::nullUnit()); u.append(CMassUnit::g()); u.append(CMassUnit::kg()); u.append(CMassUnit::lb()); @@ -476,6 +532,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CPressureUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + typedef Centi PascalsToHectopascals; struct PsiToHectopascals { static double factor() { return 68.948; } }; struct InchesToHectopascals { static double factor() { return 33.86389; } }; @@ -500,6 +560,15 @@ namespace BlackMisc */ static const CPressureUnit &defaultUnit() { return hPa(); } + /*! + * \brief Null unit + */ + static const CPressureUnit &nullUnit() + { + static CPressureUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Pascal */ @@ -571,6 +640,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CPressureUnit::nullUnit()); u.append(CPressureUnit::bar()); u.append(CPressureUnit::hPa()); u.append(CPressureUnit::inHg()); @@ -604,6 +674,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CTemperatureUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + struct KelvinToCentigrade { static double factor() { return 1.0; } @@ -634,6 +708,15 @@ namespace BlackMisc */ static const CTemperatureUnit &defaultUnit() { return C(); } + /*! + * \brief Null unit + */ + static const CTemperatureUnit &nullUnit() + { + static CTemperatureUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Kelvin */ @@ -669,6 +752,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CTemperatureUnit::nullUnit()); u.append(CTemperatureUnit::C()); u.append(CTemperatureUnit::F()); u.append(CTemperatureUnit::K()); @@ -699,6 +783,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CSpeedUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + struct KnotsToMps { static double factor() { return 1852.0 / 3600.0; } }; struct KphToMps { static double factor() { return 1.0 / 3.6; } }; struct FtPerSecToMps { static double factor() { return 0.3048 ; } }; @@ -723,6 +811,15 @@ namespace BlackMisc */ static const CSpeedUnit &defaultUnit() { return m_s(); } + /*! + * Null unit + */ + static const CSpeedUnit &nullUnit() + { + static CSpeedUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Meter/second m/s */ @@ -785,6 +882,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CSpeedUnit::nullUnit()); u.append(CSpeedUnit::ft_min()); u.append(CSpeedUnit::ft_s()); u.append(CSpeedUnit::km_h()); @@ -818,6 +916,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CTimeUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + typedef One SecondsToSeconds; struct DaysToSeconds { static double factor() { return 60.0 * 60.0 * 24.0; } }; struct HoursToSeconds { static double factor() { return 60.0 * 60.0; } }; @@ -842,6 +944,15 @@ namespace BlackMisc */ static const CTimeUnit &defaultUnit() { return s(); } + /*! + * Null unit + */ + static const CTimeUnit &nullUnit() + { + static CTimeUnit nu("null", "null", nullptr); + return nu; + } + /*! * \copydoc CMeasurementUnit::makeRoundedQStringWithUnit */ @@ -933,6 +1044,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CTimeUnit::nullUnit()); u.append(CTimeUnit::d()); u.append(CTimeUnit::h()); u.append(CTimeUnit::min()); @@ -965,6 +1077,10 @@ namespace BlackMisc CMeasurementUnit(name, symbol, converter, displayDigits, epsilon) {} + CAccelerationUnit(const QString &name, const QString &symbol, std::nullptr_t) : + CMeasurementUnit(name, symbol, nullptr) + {} + struct FeetToMeters { static double factor() { return 0.3048; } }; public: @@ -986,6 +1102,15 @@ namespace BlackMisc */ static const CAccelerationUnit &defaultUnit() { return m_s2(); } + /*! + * Null unit + */ + static const CAccelerationUnit &nullUnit() + { + static CAccelerationUnit nu("null", "null", nullptr); + return nu; + } + /*! * \brief Meter/second^2 (m/s^2) */ @@ -1012,6 +1137,7 @@ namespace BlackMisc static QList u; if (u.isEmpty()) { + u.append(CAccelerationUnit::nullUnit()); u.append(CAccelerationUnit::ft_s2()); u.append(CAccelerationUnit::m_s2()); }