/* Copyright (C) 2013 VATSIM Community / contributors * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "blackmisc/pqallquantities.h" #include "blackmiscfreefunctions.h" namespace BlackMisc { namespace PhysicalQuantities { /* * Constructor by double */ template CPhysicalQuantity::CPhysicalQuantity(double value, const MU &unit) : m_value(value), m_unit(unit) { // void } /* * Copy constructor * (The implicitly generated copy constructor would suffice, but for what seems to be a bug in MSVC2010 template instantiation) */ template CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &other) : CValueObject(), m_value(other.m_value), m_unit(other.m_unit) { // void } /* * Equal operator == */ template bool CPhysicalQuantity::operator ==(const CPhysicalQuantity &other) const { if (this == &other) return true; double diff = std::abs(this->m_value - other.value(this->m_unit)); return diff <= this->m_unit.getEpsilon(); } /* * Not equal */ template bool CPhysicalQuantity::operator !=(const CPhysicalQuantity &other) const { return !((*this) == other); } /* * Plus operator */ template CPhysicalQuantity &CPhysicalQuantity::operator +=(const CPhysicalQuantity &other) { this->m_value += other.value(this->m_unit); return *this; } /* * Plus operator */ template PQ CPhysicalQuantity::operator +(const PQ &other) const { PQ copy(other); copy += *this; return copy; } /* * Explicit plus */ template void CPhysicalQuantity::addValueSameUnit(double value) { this->m_value += value; } /* * Explicit minus */ template void CPhysicalQuantity::substractValueSameUnit(double value) { this->m_value -= value; } /* * Minus operator */ template CPhysicalQuantity &CPhysicalQuantity::operator -=(const CPhysicalQuantity &other) { this->m_value -= other.value(this->m_unit); return *this; } /* * Minus operator */ template PQ CPhysicalQuantity::operator -(const PQ &other) const { PQ copy = *derived(); copy -= other; return copy; } /* * Marshall */ template void CPhysicalQuantity::marshallToDbus(QDBusArgument &argument) const { argument << this->value(UnitClass::defaultUnit()); argument << this->m_value; argument << this->m_unit; } /* * Unmarshall */ template void CPhysicalQuantity::unmarshallFromDbus(const QDBusArgument &argument) { double ignore; argument >> ignore; argument >> this->m_value; argument >> this->m_unit; } /* * Register metatype */ template void CPhysicalQuantity::registerMetadata() { qRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType >(); qRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType >(); } /* * Multiply operator */ template CPhysicalQuantity &CPhysicalQuantity::operator *=(double factor) { this->m_value *= factor; return *this; } /* * Multiply operator */ template PQ CPhysicalQuantity::operator *(double factor) const { PQ copy = *derived(); copy *= factor; return copy; } /* * Divide operator /= */ template CPhysicalQuantity &CPhysicalQuantity::operator /=(double divisor) { this->m_value /= divisor; return *this; } /* * Divide operator / */ template PQ CPhysicalQuantity::operator /(double divisor) const { PQ copy = *derived(); copy /= divisor; return copy; } /* * Less operator < */ template bool CPhysicalQuantity::operator <(const CPhysicalQuantity &other) const { if ((*this) == other) return false; return (this->m_value < other.value(this->m_unit)); } /* * Greater than */ template bool CPhysicalQuantity::operator >(const CPhysicalQuantity &other) const { if (this == &other) return false; return other < *this; } /* * Greater / Equal */ template bool CPhysicalQuantity::operator >=(const CPhysicalQuantity &other) const { if (this == &other) return true; return !(*this < other); } /* * Less equal */ template bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &other) const { if (this == &other) return true; return !(*this > other); } /* * Switch to another unit */ template PQ &CPhysicalQuantity::switchUnit(const MU &newUnit) { if (this->m_unit != newUnit) { this->m_value = newUnit.convertFrom(this->m_value, this->m_unit); this->m_unit = newUnit; } return *derived(); } /* * Init by double */ template void CPhysicalQuantity::setValueSameUnit(double baseValue) { this->m_value = baseValue; } /* * Value rounded in unit */ template QString CPhysicalQuantity::valueRoundedWithUnit(const MU &unit, int digits, bool i18n) const { return unit.makeRoundedQStringWithUnit(this->value(unit), digits, i18n); } /* * Value rounded in unit */ template double CPhysicalQuantity::valueRounded(const MU &unit, int digits) const { return unit.roundValue(this->value(unit), digits); } /* * Value in unit */ template double CPhysicalQuantity::value(const MU &unit) const { return unit.convertFrom(this->m_value, this->m_unit); } /* * Convert to string */ template QString CPhysicalQuantity::convertToQString(bool i18n) const { return this->valueRoundedWithUnit(this->getUnit(), -1, i18n); } /* * Hash */ template uint CPhysicalQuantity::getValueHash() const { QList hashs; // there is no double qHash // also unit and rounding has to be considered hashs << qHash(this->valueRoundedWithUnit(MU::defaultUnit())); return BlackMisc::calculateHash(hashs, "PQ"); } /* * metaTypeId */ template int CPhysicalQuantity::getMetaTypeId() const { return qMetaTypeId(); } /* * is a */ template bool CPhysicalQuantity::isA(int metaTypeId) const { if (metaTypeId == qMetaTypeId()) { return true; } return this->CValueObject::isA(metaTypeId); } /* * Compare */ template int CPhysicalQuantity::compareImpl(const CValueObject &otherBase) const { const auto &other = static_cast(otherBase); if (*this < other) { return -1; } else if (*this > other) { return 1; } else { return 0; } } // see here for the reason of thess forward instantiations // 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; template class CPhysicalQuantity; template class CPhysicalQuantity; } // namespace } // namespace