From db4c05dd9f15f615e1edb818dafbfe73d496415a Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Tue, 14 Jan 2014 00:45:19 +0000 Subject: [PATCH] refs #84 removed the CValueObject::compare method and added a friend function BlackMisc::compare to replace it. The new compare is implemented using "multimethods" described in the book Advanced C++ Programming Styles and Idioms by James Coplien. First, the isA method is used to determine which of the values being compared is the most general. (For example, CLength is more general than CAltitude.) Then the compareImpl method is called on the most general value, with the other value as an argument. If there is not a direct inheritance relation between the two values (or they are the same class) then the comparison is invalid and a assert is triggered. --- src/blackmisc/avaircraft.cpp | 27 ++++++++++++--- src/blackmisc/avaircraft.h | 20 ++++++++--- src/blackmisc/avaircrafticao.cpp | 34 +++++++++++++++++++ src/blackmisc/avaircrafticao.h | 15 +++++++++ src/blackmisc/avaircraftsituation.cpp | 27 +++++++++++++++ src/blackmisc/avaircraftsituation.h | 15 +++++++++ src/blackmisc/avaltitude.cpp | 42 +++++++++++++++--------- src/blackmisc/avaltitude.h | 26 ++++++++------- src/blackmisc/avatcstation.cpp | 27 ++++++++++++--- src/blackmisc/avatcstation.h | 20 ++++++++--- src/blackmisc/avcallsign.cpp | 24 ++++++++++---- src/blackmisc/avcallsign.h | 26 ++++++++------- src/blackmisc/avinformationmessage.cpp | 30 +++++++++++++++++ src/blackmisc/avinformationmessage.h | 15 +++++++++ src/blackmisc/aviobase.h | 20 +++++++++++ src/blackmisc/blackmiscfreefunctions.cpp | 2 +- src/blackmisc/containerbase.h | 30 +++++++++++++++++ src/blackmisc/coordinategeodetic.cpp | 32 ++++++++++++++++++ src/blackmisc/coordinategeodetic.h | 15 +++++++++ src/blackmisc/geoearthangle.cpp | 31 +++++++++++++---- src/blackmisc/geoearthangle.h | 29 ++++++++-------- src/blackmisc/mathmatrixbase.cpp | 36 ++++++++++++++++++++ src/blackmisc/mathmatrixbase.h | 15 +++++++++ src/blackmisc/mathvector3dbase.cpp | 34 +++++++++++++++++++ src/blackmisc/mathvector3dbase.h | 15 +++++++++ src/blackmisc/nwserver.cpp | 34 +++++++++++++++++++ src/blackmisc/nwserver.h | 15 +++++++++ src/blackmisc/nwtextmessage.cpp | 28 ++++++++++++++++ src/blackmisc/nwtextmessage.h | 15 +++++++++ src/blackmisc/nwuser.cpp | 34 +++++++++++++++++++ src/blackmisc/nwuser.h | 15 +++++++++ src/blackmisc/pqbase.cpp | 27 +++++++++++++++ src/blackmisc/pqbase.h | 15 +++++++++ src/blackmisc/pqphysicalquantity.cpp | 27 ++++++++++----- src/blackmisc/pqphysicalquantity.h | 25 ++++++++------ src/blackmisc/setnetwork.cpp | 27 +++++++++++++++ src/blackmisc/setnetwork.h | 15 +++++++++ src/blackmisc/statusmessage.cpp | 30 +++++++++++++++++ src/blackmisc/statusmessage.h | 15 +++++++++ src/blackmisc/valuemap.cpp | 27 +++++++++++++++ src/blackmisc/valuemap.h | 15 +++++++++ src/blackmisc/valueobject.cpp | 18 +++++++--- src/blackmisc/valueobject.h | 42 +++++++++++++++++++----- src/blackmisc/vaudiodevice.cpp | 34 +++++++++++++++++++ src/blackmisc/vaudiodevice.h | 15 +++++++++ src/blackmisc/vvoiceroom.cpp | 35 +++++++++++++++++++- src/blackmisc/vvoiceroom.h | 15 +++++++++ tests/blackmisc/testvariantandmap.cpp | 4 +++ 48 files changed, 1015 insertions(+), 119 deletions(-) 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"); } /*