diff --git a/src/blackmisc/avaircraft.cpp b/src/blackmisc/avaircraft.cpp index c22ba7609..eb35a6291 100644 --- a/src/blackmisc/avaircraft.cpp +++ b/src/blackmisc/avaircraft.cpp @@ -124,15 +124,32 @@ namespace BlackMisc return BlackMisc::calculateHash(hashs, "CAircraft"); } + /* + * metaTypeId + */ + int CAircraft::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraft::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + /* * Compare */ - int CAircraft::compare(const QVariant &qv) const + int CAircraft::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - CAircraft aircraft = qv.value(); - return this->getCallsign().compare(aircraft.getCallsign()); + const auto &other = static_cast(otherBase); + + return this->getCallsign().asString().compare(other.getCallsign().asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avaircraft.h b/src/blackmisc/avaircraft.h index ec0de50e9..df248cd36 100644 --- a/src/blackmisc/avaircraft.h +++ b/src/blackmisc/avaircraft.h @@ -278,11 +278,6 @@ namespace BlackMisc */ virtual uint getValueHash() const; - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - /*! * \brief Register metadata */ @@ -337,6 +332,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaircrafticao.cpp b/src/blackmisc/avaircrafticao.cpp index f5ea876c0..4609465e4 100644 --- a/src/blackmisc/avaircrafticao.cpp +++ b/src/blackmisc/avaircrafticao.cpp @@ -1,5 +1,6 @@ #include "avaircrafticao.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -19,6 +20,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAircraftIcao::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraftIcao::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAircraftIcao::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_designator, this->m_color, this->m_airline, this->m_livery); + const auto rhs = std::tie(other.m_designator, other.m_color, other.m_airline, other.m_livery); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avaircrafticao.h b/src/blackmisc/avaircrafticao.h index 7011fcc57..046cd2167 100644 --- a/src/blackmisc/avaircrafticao.h +++ b/src/blackmisc/avaircrafticao.h @@ -214,6 +214,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaircraftsituation.cpp b/src/blackmisc/avaircraftsituation.cpp index aae2813b1..c0febe914 100644 --- a/src/blackmisc/avaircraftsituation.cpp +++ b/src/blackmisc/avaircraftsituation.cpp @@ -23,6 +23,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAircraftSituation::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraftSituation::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAircraftSituation::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avaircraftsituation.h b/src/blackmisc/avaircraftsituation.h index b27603fe1..068d1275e 100644 --- a/src/blackmisc/avaircraftsituation.h +++ b/src/blackmisc/avaircraftsituation.h @@ -233,6 +233,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaltitude.cpp b/src/blackmisc/avaltitude.cpp index 789d2447b..fd932668d 100644 --- a/src/blackmisc/avaltitude.cpp +++ b/src/blackmisc/avaltitude.cpp @@ -58,26 +58,36 @@ namespace BlackMisc return !((*this) == other); } + /* + * metaTypeId + */ + int CAltitude::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAltitude::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CLength::isA(metaTypeId); + } + /* * Compare */ - int CAltitude::compare(const QVariant &qv) const + int CAltitude::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert() || qv.canConvert()); - Q_ASSERT(qv.isValid() && !qv.isNull()); - if (qv.canConvert()) - { - CAltitude other = qv.value(); - if (this->isMeanSeaLevel() && other.isAboveGroundLevel()) return 1; - if (this->isAboveGroundLevel() && other.isMeanSeaLevel()) return -1; - return this->compare(other); - } - else if (qv.canConvert()) - { - return this->compare(qv.value()); - } - qFatal("Invalid comparison"); - return 0; // just for compiler + const auto &other = static_cast(otherBase); + + if (this->isMeanSeaLevel() && other.isAboveGroundLevel()) { return 1; } + if (this->isAboveGroundLevel() && other.isMeanSeaLevel()) { return -1; } + if (*this < other) { return -1; } + if (*this > other) { return 1; } + return 0; } /* diff --git a/src/blackmisc/avaltitude.h b/src/blackmisc/avaltitude.h index 8a957c92a..48b79682d 100644 --- a/src/blackmisc/avaltitude.h +++ b/src/blackmisc/avaltitude.h @@ -39,6 +39,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument @@ -122,17 +137,6 @@ namespace BlackMisc return m_datum; } - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * \todo this is a hack, to avoid hiding inherited names in CPhysicalQuantity - * (see Effective C++ item 33) CPhysicalQuantity::compare is the real culprit - */ - int compare(const CLength &other) const { return static_cast(this)->compare(other); } - /*! * \brief Register metadata */ diff --git a/src/blackmisc/avatcstation.cpp b/src/blackmisc/avatcstation.cpp index e5d8d05e9..42c30bcf4 100644 --- a/src/blackmisc/avatcstation.cpp +++ b/src/blackmisc/avatcstation.cpp @@ -429,15 +429,32 @@ namespace BlackMisc } } + /* + * metaTypeId + */ + int CAtcStation::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAtcStation::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + /* * Compare */ - int CAtcStation::compare(const QVariant &qv) const + int CAtcStation::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - CAtcStation atc = qv.value(); - return this->getCallsign().compare(atc.getCallsign()); + const auto &other = static_cast(otherBase); + + return this->getCallsign().asString().compare(other.getCallsign().asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avatcstation.h b/src/blackmisc/avatcstation.h index 801411ec7..7c93e8648 100644 --- a/src/blackmisc/avatcstation.h +++ b/src/blackmisc/avatcstation.h @@ -453,11 +453,6 @@ namespace BlackMisc */ static void registerMetadata(); - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - protected: /*! * \brief Meaningful string representation @@ -466,6 +461,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avcallsign.cpp b/src/blackmisc/avcallsign.cpp index 5dbc48f72..460f871ab 100644 --- a/src/blackmisc/avcallsign.cpp +++ b/src/blackmisc/avcallsign.cpp @@ -98,21 +98,31 @@ namespace BlackMisc } /* - * Compare + * metaTypeId */ - int CCallsign::compare(const QVariant &qv) const + int CCallsign::getMetaTypeId() const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - return this->compare(qv.value()); + return qMetaTypeId(); + } + + /* + * is a + */ + bool CCallsign::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); } /* * Compare */ - int CCallsign::compare(const CCallsign &callsign) const + int CCallsign::compareImpl(const CValueObject &otherBase) const { - return this->m_callsign.compare(callsign.asString(), Qt::CaseInsensitive); + const auto &other = static_cast(otherBase); + + return this->m_callsign.compare(other.asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avcallsign.h b/src/blackmisc/avcallsign.h index 538466cdb..b237b4fca 100644 --- a/src/blackmisc/avcallsign.h +++ b/src/blackmisc/avcallsign.h @@ -121,17 +121,6 @@ namespace BlackMisc */ virtual uint getValueHash() const; - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * Compare with other callsign - * \return - */ - virtual int compare(const CCallsign &callsign) const; - /*! * \brief Register metadata */ @@ -145,6 +134,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avinformationmessage.cpp b/src/blackmisc/avinformationmessage.cpp index 26efcdfa5..be9a3324d 100644 --- a/src/blackmisc/avinformationmessage.cpp +++ b/src/blackmisc/avinformationmessage.cpp @@ -13,6 +13,36 @@ namespace BlackMisc return this->m_message; } + /* + * metaTypeId + */ + int CInformationMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CInformationMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CInformationMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + if (this->m_type < other.m_type) { return -1; } + if (this->m_type > other.m_type) { return 1; } + return this->m_message.compare(other.m_message); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avinformationmessage.h b/src/blackmisc/avinformationmessage.h index f04484299..6a2db3acf 100644 --- a/src/blackmisc/avinformationmessage.h +++ b/src/blackmisc/avinformationmessage.h @@ -164,6 +164,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/aviobase.h b/src/blackmisc/aviobase.h index 1cac99ccd..160503b44 100644 --- a/src/blackmisc/aviobase.h +++ b/src/blackmisc/aviobase.h @@ -58,6 +58,26 @@ namespace BlackMisc return this->m_name == other.m_name; } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const { return 0; } + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const { return this->CValueObject::isA(metaTypeId); } + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const + { + Q_UNUSED(other); + qFatal("not implemented"); + return 0; + } + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/blackmiscfreefunctions.cpp b/src/blackmisc/blackmiscfreefunctions.cpp index 49abec738..2e70c2ac3 100644 --- a/src/blackmisc/blackmiscfreefunctions.cpp +++ b/src/blackmisc/blackmiscfreefunctions.cpp @@ -221,7 +221,7 @@ int BlackMisc:: compareQVariants(const QVariant &v1, const QVariant &v2) const CValueObject *cs2 = CValueObject::fromQVariant(v2); if (cs1 && cs2) { - return cs1->compare(v2); // Note, that I have to compare against QVariant + return compare(*cs1, *cs2); } } diff --git a/src/blackmisc/containerbase.h b/src/blackmisc/containerbase.h index 299581fa8..df6052cd2 100644 --- a/src/blackmisc/containerbase.h +++ b/src/blackmisc/containerbase.h @@ -152,6 +152,36 @@ namespace BlackMisc return str += "}"; } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const { return qMetaTypeId>(); } + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId>()) { return true; } + return CValueObject::isA(metaTypeId); + } + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &/*other*/) const + { + //const auto &o = static_cast(other); + //if (derived().size() < o.derived().size()) { return -1; } + //if (derived().size() > o.derived().size()) { return 1; } + //for (auto i1 = derived().begin(), i2 = o.derived().begin(); i1 != derived().end() && i2 != o.derived().end(); ++i1, ++i2) + //{ + // if (*i1 < *i2) { return -1; } + // if (*i1 > *i2) { return 1; } + //} + return 0; + } + virtual void marshallToDbus(QDBusArgument &argument) const { argument.beginArray(qMetaTypeId()); diff --git a/src/blackmisc/coordinategeodetic.cpp b/src/blackmisc/coordinategeodetic.cpp index ef6914f05..e3f09db00 100644 --- a/src/blackmisc/coordinategeodetic.cpp +++ b/src/blackmisc/coordinategeodetic.cpp @@ -25,6 +25,38 @@ namespace BlackMisc return s.arg(this->m_latitude.valueRoundedWithUnit(6, i18n)).arg(this->m_longitude.valueRoundedWithUnit(6, i18n)).arg(this->m_height.valueRoundedWithUnit(i18n)); } + /* + * metaTypeId + */ + int CCoordinateGeodetic::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CCoordinateGeodetic::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CCoordinateGeodetic::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + int cmp = compare(this->m_latitude, other.m_latitude); + if (cmp) { return cmp; } + cmp = compare(this->m_longitude, other.m_longitude); + if (cmp) { return cmp; } + return compare(this->m_height, other.m_height); + } + /* * Marshall to Dbus */ diff --git a/src/blackmisc/coordinategeodetic.h b/src/blackmisc/coordinategeodetic.h index 6c9efab22..9354d668d 100644 --- a/src/blackmisc/coordinategeodetic.h +++ b/src/blackmisc/coordinategeodetic.h @@ -82,6 +82,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/geoearthangle.cpp b/src/blackmisc/geoearthangle.cpp index 7ddcf9553..23e769793 100644 --- a/src/blackmisc/geoearthangle.cpp +++ b/src/blackmisc/geoearthangle.cpp @@ -71,17 +71,34 @@ namespace BlackMisc return LATorLON(a); } + /* + * metaTypeId + */ + template int CEarthAngle::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CEarthAngle::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CAngle::isA(metaTypeId); + } + /* * Compare */ - template int CEarthAngle::compare(const QVariant &qv) const + template int CEarthAngle::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert() || qv.canConvert()); - Q_ASSERT(qv.isValid() && !qv.isNull()); - if (qv.canConvert()) - return this->compare(qv.value()); - else - return this->compare(qv.value()); + 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 diff --git a/src/blackmisc/geoearthangle.h b/src/blackmisc/geoearthangle.h index 891263f97..c17b5c010 100644 --- a/src/blackmisc/geoearthangle.h +++ b/src/blackmisc/geoearthangle.h @@ -45,6 +45,21 @@ namespace BlackMisc return this->valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CAngleUnit::deg(), 6, i18n); } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument @@ -175,20 +190,6 @@ namespace BlackMisc return l; } - /*! - * Compare - */ - int compare(const QVariant &qv) const; - - /*! - * \todo this is a hack, to avoid hiding inherited names in CPhysicalQuantity - * (see Effective C++ item 33) CPhysicalQuantity::compare is the real culprit - */ - int compare(const CEarthAngle &other) const - { - return static_cast *>(this)->compare(other); - } - /*! * Register metadata */ diff --git a/src/blackmisc/mathmatrixbase.cpp b/src/blackmisc/mathmatrixbase.cpp index 1ecfb4579..676500bb2 100644 --- a/src/blackmisc/mathmatrixbase.cpp +++ b/src/blackmisc/mathmatrixbase.cpp @@ -138,6 +138,42 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + template int CMatrixBase::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CMatrixBase::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + template int CMatrixBase::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + for (int r = 0; r < Rows; ++r) + { + for (int c = 0; c < Columns; ++c) + { + if (this->m_matrix(r, c) < other.m_matrix(r, c)) { return -1; } + if (this->m_matrix(r, c) > other.m_matrix(r, c)) { return 1; } + } + } + return 0; + } + /* * Hash */ diff --git a/src/blackmisc/mathmatrixbase.h b/src/blackmisc/mathmatrixbase.h index c373def3b..d06ad3c30 100644 --- a/src/blackmisc/mathmatrixbase.h +++ b/src/blackmisc/mathmatrixbase.h @@ -51,6 +51,21 @@ namespace BlackMisc */ QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/mathvector3dbase.cpp b/src/blackmisc/mathvector3dbase.cpp index 6eb34e284..133eb3b66 100644 --- a/src/blackmisc/mathvector3dbase.cpp +++ b/src/blackmisc/mathvector3dbase.cpp @@ -8,6 +8,7 @@ #include "blackmisc/coordinateecef.h" #include "blackmisc/coordinatened.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -26,6 +27,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + template int CVector3DBase::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CVector3DBase::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + template int CVector3DBase::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_i, this->m_j, this->m_k); + const auto rhs = std::tie(other.m_i, other.m_j, other.m_k); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Vector to zero */ diff --git a/src/blackmisc/mathvector3dbase.h b/src/blackmisc/mathvector3dbase.h index 76efe48ff..2d65ebe15 100644 --- a/src/blackmisc/mathvector3dbase.h +++ b/src/blackmisc/mathvector3dbase.h @@ -80,6 +80,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Unmarshall from Dbus * \param argument diff --git a/src/blackmisc/nwserver.cpp b/src/blackmisc/nwserver.cpp index 0095d0ae5..195d54837 100644 --- a/src/blackmisc/nwserver.cpp +++ b/src/blackmisc/nwserver.cpp @@ -1,5 +1,6 @@ #include "nwserver.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -18,6 +19,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CServer::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CServer::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CServer::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_name, this->m_description, this->m_address, this->m_port); + const auto rhs = std::tie(other.m_name, other.m_description, other.m_address, other.m_port); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return compare(this->m_user, other.m_user); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwserver.h b/src/blackmisc/nwserver.h index 7e95b3a2d..9e47ec84c 100644 --- a/src/blackmisc/nwserver.h +++ b/src/blackmisc/nwserver.h @@ -181,6 +181,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/nwtextmessage.cpp b/src/blackmisc/nwtextmessage.cpp index 9ac6867c7..a6786ed02 100644 --- a/src/blackmisc/nwtextmessage.cpp +++ b/src/blackmisc/nwtextmessage.cpp @@ -28,6 +28,34 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CTextMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CTextMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CTextMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + return this->m_message.compare(other.m_message); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwtextmessage.h b/src/blackmisc/nwtextmessage.h index b7576ed45..5b9a4bd62 100644 --- a/src/blackmisc/nwtextmessage.h +++ b/src/blackmisc/nwtextmessage.h @@ -234,6 +234,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/nwuser.cpp b/src/blackmisc/nwuser.cpp index 43c82221c..69e9aa41b 100644 --- a/src/blackmisc/nwuser.cpp +++ b/src/blackmisc/nwuser.cpp @@ -1,5 +1,6 @@ #include "nwuser.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -19,6 +20,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CUser::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CUser::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CUser::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_id, this->m_realname, this->m_email, this->m_password); + const auto rhs = std::tie(other.m_id, other.m_realname, other.m_email, other.m_password); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwuser.h b/src/blackmisc/nwuser.h index 20c5de54b..f28af504b 100644 --- a/src/blackmisc/nwuser.h +++ b/src/blackmisc/nwuser.h @@ -185,6 +185,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/pqbase.cpp b/src/blackmisc/pqbase.cpp index cef13d6c9..c9aac01ad 100644 --- a/src/blackmisc/pqbase.cpp +++ b/src/blackmisc/pqbase.cpp @@ -74,6 +74,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CMeasurementUnit::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CMeasurementUnit::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CMeasurementUnit::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /*! * \brief Register metadata of unit and quantity */ diff --git a/src/blackmisc/pqbase.h b/src/blackmisc/pqbase.h index 30b7860f7..e5e5a9b99 100644 --- a/src/blackmisc/pqbase.h +++ b/src/blackmisc/pqbase.h @@ -230,6 +230,21 @@ namespace BlackMisc return this->getSymbol(i18n); } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/pqphysicalquantity.cpp b/src/blackmisc/pqphysicalquantity.cpp index b8f52a4c0..436ad1624 100644 --- a/src/blackmisc/pqphysicalquantity.cpp +++ b/src/blackmisc/pqphysicalquantity.cpp @@ -266,22 +266,33 @@ namespace BlackMisc } /* - * Compare + * metaTypeId */ - template int CPhysicalQuantity::compare(const QVariant &qv) const + template int CPhysicalQuantity::getMetaTypeId() const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - return this->compare(qv.value()); + 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::compare(const PQ &other) const + template int CPhysicalQuantity::compareImpl(const CValueObject &otherBase) const { - if (other == (*this)) return 0; - return ((*this) < other) ? -1 : 1; + 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 diff --git a/src/blackmisc/pqphysicalquantity.h b/src/blackmisc/pqphysicalquantity.h index 15fb2cc48..841a6cdaf 100644 --- a/src/blackmisc/pqphysicalquantity.h +++ b/src/blackmisc/pqphysicalquantity.h @@ -68,6 +68,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + public: /*! * \brief Virtual destructor @@ -357,16 +372,6 @@ namespace BlackMisc * \brief Register metadata of unit and quantity */ static void registerMetadata(); - - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const PQ &other) const; }; } // namespace diff --git a/src/blackmisc/setnetwork.cpp b/src/blackmisc/setnetwork.cpp index 92a19a11b..560dd1e54 100644 --- a/src/blackmisc/setnetwork.cpp +++ b/src/blackmisc/setnetwork.cpp @@ -34,6 +34,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CSettingsNetwork::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CSettingsNetwork::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CSettingsNetwork::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/setnetwork.h b/src/blackmisc/setnetwork.h index b7af81f2e..4a9bb0775 100644 --- a/src/blackmisc/setnetwork.h +++ b/src/blackmisc/setnetwork.h @@ -132,6 +132,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/statusmessage.cpp b/src/blackmisc/statusmessage.cpp index 9160dae63..9501d1ba7 100644 --- a/src/blackmisc/statusmessage.cpp +++ b/src/blackmisc/statusmessage.cpp @@ -33,6 +33,36 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CStatusMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CStatusMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CStatusMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + if (this->m_type < other.m_type) { return -1; } + if (this->m_type > other.m_type) { return 1; } + return this->m_message.compare(other.m_message); + } + /* * Metadata */ diff --git a/src/blackmisc/statusmessage.h b/src/blackmisc/statusmessage.h index d7fced67b..3b8054712 100644 --- a/src/blackmisc/statusmessage.h +++ b/src/blackmisc/statusmessage.h @@ -147,6 +147,21 @@ namespace BlackMisc * \return */ virtual QString convertToQString(bool i18n = false) const; + + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; }; } diff --git a/src/blackmisc/valuemap.cpp b/src/blackmisc/valuemap.cpp index 865c7122d..02bfd12cb 100644 --- a/src/blackmisc/valuemap.cpp +++ b/src/blackmisc/valuemap.cpp @@ -38,6 +38,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CValueMap::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CValueMap::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CValueMap::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/valuemap.h b/src/blackmisc/valuemap.h index be08dbf29..02f9a19f9 100644 --- a/src/blackmisc/valuemap.h +++ b/src/blackmisc/valuemap.h @@ -131,6 +131,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/valueobject.cpp b/src/blackmisc/valueobject.cpp index 0fd03beb2..47a4b2a36 100644 --- a/src/blackmisc/valueobject.cpp +++ b/src/blackmisc/valueobject.cpp @@ -87,11 +87,21 @@ namespace BlackMisc /* * Compare */ - int CValueObject::compare(const QVariant & /** qv **/) const + int compare(const CValueObject &v1, const CValueObject &v2) { - // not all classes have to implement this - qFatal("Property by index as string not implemented"); - return -1; // avoid compiler warning + if (v1.isA(v2.getMetaTypeId())) + { + return v2.compareImpl(v1) * -1; + } + else if (v2.isA(v1.getMetaTypeId())) + { + return v1.compareImpl(v2); + } + else + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Attempt to compare between instances of unrelated classes"); + return 0; + } } /*! diff --git a/src/blackmisc/valueobject.h b/src/blackmisc/valueobject.h index d38072bbd..e011272fc 100644 --- a/src/blackmisc/valueobject.h +++ b/src/blackmisc/valueobject.h @@ -141,6 +141,15 @@ namespace BlackMisc */ friend bool operator!=(const CValueObject &uc, const CValueMap &valueMap); + /*! + * Compares two instances of related classes + * and returns an integer less than, equal to, or greater than zero + * if v1 is less than, equal to, or greater than v2. + * \return + * \pre The runtime types of the two objects must be the same or related by inheritance. + */ + friend int compare(const CValueObject &v1, const CValueObject &v2); + public: /*! * \brief Virtual destructor @@ -179,15 +188,6 @@ namespace BlackMisc */ virtual uint getValueHash() const = 0; - /*! - * Compares with QVariant with this object - * and returns an integer less than, equal to, or greater than zero - * if this is less than, equal to, or greater than QVariant. - * \remarks allows sorting among QVariants, not all classes implement this - * \return - */ - virtual int compare(const QVariant &qv) const; - /*! * \brief Virtual method to return QVariant, used with DBUS QVariant lists * \return @@ -257,6 +257,30 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const = 0; + /*! + * \brief Returns the Qt meta type ID of this object. + * \return + */ + virtual int getMetaTypeId() const = 0; + + /*! + * \brief Returns true if this object is an instance of the class with the given meta type ID, + * or one of its subclasses. + * \param metaTypeId + * \return + */ + virtual bool isA(int metaTypeId) const { Q_UNUSED(metaTypeId); return false; } + + /*! + * \brief Compare this value with another value of the same type + * \param other + * \return Less than, equal to, or greater than zero if this is + * less than, equal to, or greather than other. + * \pre Other must have the same runtime type as the this object. + * \remark It is usually safer to use the friend function compare() instead. + */ + virtual int compareImpl(const CValueObject &other) const = 0; + /*! * \brief Marshall to DBus * \param argument diff --git a/src/blackmisc/vaudiodevice.cpp b/src/blackmisc/vaudiodevice.cpp index 7208d5c36..4bbd1411e 100644 --- a/src/blackmisc/vaudiodevice.cpp +++ b/src/blackmisc/vaudiodevice.cpp @@ -10,6 +10,7 @@ #include "vaudiodevice.h" #include "blackmisc/blackmiscfreefunctions.h" #include +#include namespace BlackMisc { @@ -90,6 +91,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAudioDevice::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAudioDevice::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAudioDevice::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_type, this->m_deviceIndex, this->m_deviceName, this->m_hostName); + const auto rhs = std::tie(other.m_type, other.m_deviceIndex, other.m_deviceName, other.m_hostName); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/vaudiodevice.h b/src/blackmisc/vaudiodevice.h index 159518f20..4b1fca4e7 100644 --- a/src/blackmisc/vaudiodevice.h +++ b/src/blackmisc/vaudiodevice.h @@ -126,6 +126,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/vvoiceroom.cpp b/src/blackmisc/vvoiceroom.cpp index 9cd73d191..4773b0cea 100644 --- a/src/blackmisc/vvoiceroom.cpp +++ b/src/blackmisc/vvoiceroom.cpp @@ -9,9 +9,9 @@ #include "vvoiceroom.h" #include "blackmisc/blackmiscfreefunctions.h" - #include #include +#include namespace BlackMisc { @@ -85,6 +85,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CVoiceRoom::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CVoiceRoom::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CVoiceRoom::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(m_hostname, m_channel, m_connected, m_audioPlaying); + const auto rhs = std::tie(other.m_hostname, other.m_channel, other.m_connected, other.m_audioPlaying); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/vvoiceroom.h b/src/blackmisc/vvoiceroom.h index 5bd5d32d8..acd57dcb6 100644 --- a/src/blackmisc/vvoiceroom.h +++ b/src/blackmisc/vvoiceroom.h @@ -166,6 +166,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/tests/blackmisc/testvariantandmap.cpp b/tests/blackmisc/testvariantandmap.cpp index 44e49c6c5..a9a145d18 100644 --- a/tests/blackmisc/testvariantandmap.cpp +++ b/tests/blackmisc/testvariantandmap.cpp @@ -46,6 +46,10 @@ namespace BlackMiscTest QVERIFY2(station1 == station1qv, "Station should be equal (QVariant)"); QVERIFY2(station2 == station1qv, "Station should be equal (QVariant)"); QVERIFY2(station3 != station1qv, "Station should be equal (QVariant)"); + + QVERIFY2(compare(station1, station1) == 0, "Station should be equal"); + QVERIFY2(compare(station1, station2) == 0, "Station should be equal"); + QVERIFY2(compare(station1, station3) != 0, "Station should not be equal"); } /*