mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-01 13:36:48 +08:00
refs #413 Decomposed hash-related functions of CValueObject into Mixin::HashByTuple.
This commit is contained in:
@@ -118,8 +118,8 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::convertFromQVariant
|
||||
virtual void convertFromQVariant(const QVariant &variant) override { BlackMisc::setFromQVariant< C<T> >(&derived(), variant); }
|
||||
|
||||
//! \copydoc BlackMisc::CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override { return qHash(&derived()); }
|
||||
//! Simplifies composition, returns 0 for performance
|
||||
friend uint qHash(const C<T> &) { return 0; }
|
||||
|
||||
//! \copydoc CValueObject::toJson
|
||||
virtual QJsonObject toJson() const override
|
||||
|
||||
@@ -232,9 +232,6 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::convertFromQVariant
|
||||
virtual void convertFromQVariant(const QVariant &variant) override { BlackMisc::setFromQVariant(this, variant); }
|
||||
|
||||
//! \copydoc BlackMisc::CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override { return qHash(this); }
|
||||
|
||||
//! \copydoc CValueObject::toJson
|
||||
virtual QJsonObject toJson() const override
|
||||
{
|
||||
|
||||
@@ -122,6 +122,10 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::CLogPattern)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CLogPattern, (o.m_severities, o.m_strategy, o.m_strings))
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CLogPattern, (
|
||||
attr(o.m_severities, flags<DisabledForHashing>()),
|
||||
attr(o.m_strategy),
|
||||
attr(o.m_strings, flags<DisabledForHashing>())
|
||||
))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -279,10 +279,10 @@ namespace BlackMisc
|
||||
//! Unequal operator !=
|
||||
bool operator != (const CMeasurementUnit &other) const;
|
||||
|
||||
//! \copydoc CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override
|
||||
//! \copydoc CValueObject::qHash
|
||||
friend uint qHash(const CMeasurementUnit &unit)
|
||||
{
|
||||
return qHash(this->getName());
|
||||
return ::qHash(unit.getName());
|
||||
}
|
||||
|
||||
//! Name such as "meter"
|
||||
|
||||
@@ -198,8 +198,11 @@ namespace BlackMisc
|
||||
//! \copydoc CValueObject::unmarshallFromDbus
|
||||
virtual void unmarshallFromDbus(const QDBusArgument &argument) override;
|
||||
|
||||
//! \copydoc CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override;
|
||||
//! \copydoc CValueObject::qHash
|
||||
uint getValueHash() const;
|
||||
|
||||
//! \copydoc CValueObject::qHash
|
||||
friend uint qHash(const PQ &pq) { return pq.getValueHash(); };
|
||||
|
||||
//! \copydoc CValueObject::toJson
|
||||
virtual QJsonObject toJson() const override;
|
||||
|
||||
@@ -137,8 +137,11 @@ namespace BlackMisc
|
||||
//! Map
|
||||
const QMap<CPropertyIndex, CVariant> &map() const { return this->m_values; }
|
||||
|
||||
//! \copydoc CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override;
|
||||
//! Hash value
|
||||
uint getValueHash() const;
|
||||
|
||||
//! \copydoc CValueObject::qHash
|
||||
friend uint qHash(const CPropertyIndexVariantMap &vm) { return vm.getValueHash(); }
|
||||
|
||||
//! \copydoc CValueObject::toQVariant
|
||||
virtual QVariant toQVariant() const override { return QVariant::fromValue(*this); }
|
||||
|
||||
@@ -110,9 +110,6 @@ namespace BlackMisc
|
||||
*/
|
||||
struct CValueObjectDummyBase
|
||||
{
|
||||
//! Value hash
|
||||
static uint getValueHash() { return 0; }
|
||||
|
||||
//! To JSON
|
||||
static QJsonObject toJson() { return {}; }
|
||||
|
||||
@@ -240,6 +237,36 @@ namespace BlackMisc
|
||||
static bool baseIsA(const CEmpty *, int) { return false; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* CRTP class template from which a derived class can inherit common methods dealing with hashing instances by metatuple.
|
||||
*/
|
||||
template <class Derived, bool IsTupleBased = true>
|
||||
class HashByTuple : private Private::EncapsulationBreaker
|
||||
{
|
||||
public:
|
||||
//! qHash overload, needed for storing value in a QSet.
|
||||
friend uint qHash(const Derived &value, uint seed = 0)
|
||||
{
|
||||
return ::qHash(hashImpl(value), seed);
|
||||
}
|
||||
|
||||
private:
|
||||
static uint hashImpl(const Derived &value)
|
||||
{
|
||||
return BlackMisc::qHash(toMetaTuple(value)) ^ baseHash(static_cast<const typename Derived::base_type &>(value));
|
||||
}
|
||||
|
||||
template <typename T> static uint baseHash(const T &base) { return qHash(base); }
|
||||
static uint baseHash(const CEmpty &) { return 0; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Specialization of HashByTuple for classes not registered with the tuple system.
|
||||
*/
|
||||
template <class Derived>
|
||||
class HashByTuple<Derived, false>
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -255,13 +282,13 @@ namespace BlackMisc
|
||||
template <class Derived, class Base /*= CEmpty*/> class CValueObject :
|
||||
public Base,
|
||||
public Mixin::MetaType<Derived>,
|
||||
public Mixin::HashByTuple<Derived, Policy::Hash::IsMetaTuple<Derived, Base>::value>,
|
||||
private CValueObjectPolicy<Derived>::Equals::template Ops<Derived, Base>,
|
||||
private CValueObjectPolicy<Derived>::LessThan::template Ops<Derived, Base>,
|
||||
private CValueObjectPolicy<Derived>::Compare::template Ops<Derived, Base>
|
||||
{
|
||||
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
|
||||
|
||||
using HashPolicy = typename CValueObjectPolicy<Derived>::Hash;
|
||||
using DBusPolicy = typename CValueObjectPolicy<Derived>::DBus;
|
||||
using JsonPolicy = typename CValueObjectPolicy<Derived>::Json;
|
||||
using PropertyIndexPolicy = typename CValueObjectPolicy<Derived>::PropertyIndex;
|
||||
@@ -356,12 +383,6 @@ namespace BlackMisc
|
||||
return json;
|
||||
}
|
||||
|
||||
//! qHash overload, needed for storing value in a QSet.
|
||||
friend uint qHash(const Derived &value, uint seed = 0)
|
||||
{
|
||||
return qHash(value.getValueHash(), seed);
|
||||
}
|
||||
|
||||
public:
|
||||
//! Base class
|
||||
using base_type = Base;
|
||||
@@ -396,12 +417,6 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Mixin::MetaType::convertFromCVariant
|
||||
using Mixin::MetaType<Derived>::convertFromCVariant;
|
||||
|
||||
//! Value hash, allows comparisons between QVariants
|
||||
virtual uint getValueHash() const
|
||||
{
|
||||
return HashPolicy::hashImpl(*derived()) ^ BaseOrDummy::getValueHash();
|
||||
}
|
||||
|
||||
//! Cast to JSON object
|
||||
virtual QJsonObject toJson() const
|
||||
{
|
||||
|
||||
@@ -283,6 +283,11 @@ namespace BlackMisc
|
||||
template <class T, class...>
|
||||
static uint hashImpl(const T &) { return 0; }
|
||||
};
|
||||
|
||||
//! \private Detect the policy of T, following inheritance.
|
||||
template <class T, class B, class P = typename CValueObjectPolicy<T>::Hash> struct IsMetaTuple : public std::false_type {};
|
||||
template <class T, class B> struct IsMetaTuple<T, B, MetaTuple> : public std::true_type {};
|
||||
template <class T, class B> struct IsMetaTuple<T, B, Inherit> : public IsMetaTuple<B, typename B::base_type> {};
|
||||
}
|
||||
|
||||
namespace DBus
|
||||
|
||||
@@ -51,6 +51,10 @@ namespace BlackMisc
|
||||
virtual bool equalsPropertyByIndex(const void *object, const CVariant &compareValue, const CPropertyIndex &index) const = 0;
|
||||
};
|
||||
|
||||
//! \private Fallback in case qHash is not defined for T.
|
||||
template <typename T>
|
||||
uint qHash(const T &) { return 0; }
|
||||
|
||||
//! \private Implementation of IValueObjectMetaInfo representing the set of operations supported by T.
|
||||
template <typename T>
|
||||
struct CValueObjectMetaInfo : public IValueObjectMetaInfo
|
||||
@@ -73,7 +77,7 @@ namespace BlackMisc
|
||||
}
|
||||
virtual uint getValueHash(const void *object) const override
|
||||
{
|
||||
return cast(object).getValueHash();
|
||||
return qHash(cast(object));
|
||||
}
|
||||
virtual int getMetaTypeId() const override
|
||||
{
|
||||
|
||||
@@ -77,8 +77,8 @@ namespace BlackMisc
|
||||
//! Construct a variant from the given type and opaque pointer.
|
||||
CVariant(int typeId, const void *copy) : m_v(typeId, copy) {}
|
||||
|
||||
//! \copydoc CValueObject::getValueHash
|
||||
virtual uint getValueHash() const override;
|
||||
//! \copydoc CValueObject::qHash
|
||||
friend uint qHash(const CVariant &var) { return var.getValueHash(); }
|
||||
|
||||
//! Change the internal QVariant.
|
||||
void reset(const QVariant &var) { m_v = var; }
|
||||
@@ -219,6 +219,7 @@ namespace BlackMisc
|
||||
const void *data() const { return m_v.data(); }
|
||||
|
||||
static int compareImpl(const CVariant &, const CVariant &);
|
||||
uint getValueHash() const;
|
||||
};
|
||||
|
||||
//! Compare stored value of CVariant with any CValueObject derived class.
|
||||
|
||||
Reference in New Issue
Block a user