refs #356 Extend CVariant to support accessing properties by index of the contained value object.

This commit is contained in:
Mathew Sutcliffe
2015-03-16 16:07:41 +00:00
parent 50bf5690f9
commit 2ea9d031ea
5 changed files with 124 additions and 3 deletions

View File

@@ -44,22 +44,54 @@ namespace BlackMisc
}
/*
* Compare with CValueObject
* Compare with CVariant
*/
bool operator==(const CPropertyIndexVariantMap &indexMap, const CValueObject &valueObject)
bool operator==(const CPropertyIndexVariantMap &indexMap, const CVariant &variant)
{
if (indexMap.isEmpty()) return indexMap.isWildcard();
const auto &map = indexMap.map();
for (auto it = map.begin(); it != map.end(); ++it)
{
// QVariant cannot be compared directly
CVariant p = valueObject.propertyByIndex(it.key()); // from value object
CVariant p = variant.propertyByIndex(it.key()); // from value object
CVariant v = it.value().toCVariant(); // from map
if (p != v) return false;
}
return true;
}
/*
* Compare with CVariant
*/
bool operator!=(const CPropertyIndexVariantMap &indexMap, const CVariant &variant)
{
return !(indexMap == variant);
}
/*
* Compare with CVariant
*/
bool operator==(const CVariant &variant, const CPropertyIndexVariantMap &valueMap)
{
return valueMap == variant;
}
/*
* Compare with CVariant
*/
bool operator!=(const CVariant &variant, const CPropertyIndexVariantMap &valueMap)
{
return !(valueMap == variant);
}
/*
* Compare with CValueObject
*/
bool operator==(const CPropertyIndexVariantMap &indexMap, const CValueObject &valueObject)
{
return indexMap == valueObject.toCVariant();
}
/*
* Compare with CValueObject
*/

View File

@@ -97,16 +97,32 @@ namespace BlackMisc
//! Equal operator, required if maps are directly compared, not with CValueObject
friend bool operator !=(const CPropertyIndexVariantMap &a, const CPropertyIndexVariantMap &b);
//! Operator == with CVariant
friend bool operator ==(const CPropertyIndexVariantMap &valueMap, const CVariant &variant);
//! Operator != with CVariant
friend bool operator !=(const CPropertyIndexVariantMap &valueMap, const CVariant &variant);
//! Operator == with CVariant
friend bool operator ==(const CVariant &variant, const CPropertyIndexVariantMap &valueMap);
//! Operator != with CVariant
friend bool operator !=(const CVariant &variant, const CPropertyIndexVariantMap &valueMap);
//! Operator == with CValueObject
//! \todo Still needed?
friend bool operator ==(const CPropertyIndexVariantMap &valueMap, const CValueObject &valueObject);
//! Operator != with CValueObject
//! \todo Still needed?
friend bool operator !=(const CPropertyIndexVariantMap &valueMap, const CValueObject &valueObject);
//! Operator == with CValueObject
//! \todo Still needed?
friend bool operator ==(const CValueObject &valueObject, const CPropertyIndexVariantMap &valueMap);
//! Operator != with CValueObject
//! \todo Still needed?
friend bool operator !=(const CValueObject &valueObject, const CPropertyIndexVariantMap &valueMap);
//! Map

View File

@@ -22,9 +22,14 @@ namespace BlackMisc
template <class T> typename std::enable_if<std::is_base_of<CValueObject, T>::value, QDBusArgument>::type const &
operator>>(const QDBusArgument &argument, T &valueObject);
class CVariant;
class CPropertyIndex;
namespace Private
{
//! \private Needed so we can copy forward-declared CVariant.
void assign(CVariant &, const CVariant &);
//! \private Abstract base class representing the set of operations supported by a particular value type.
struct IValueObjectMetaInfo
{
@@ -37,6 +42,10 @@ namespace BlackMisc
virtual int getMetaTypeId() const = 0;
virtual const void *upCastTo(const void *object, int metaTypeId) const = 0;
virtual int compare(const void *lhs, const void *rhs) const = 0;
virtual void setPropertyByIndex(void *object, const CVariant &variant, const CPropertyIndex &index) const = 0;
virtual void propertyByIndex(const void *object, CVariant &o_variant, const BlackMisc::CPropertyIndex &index) const = 0;
virtual QString propertyByIndexAsString(const void *object, const CPropertyIndex &index, bool i18n) const = 0;
virtual bool equalsPropertyByIndex(const void *object, const CVariant &compareValue, const CPropertyIndex &index) const = 0;
};
//! \private Implementation of IValueObjectMetaInfo representing the set of operations supported by T.
@@ -74,6 +83,22 @@ namespace BlackMisc
return metaTypeId == getMetaTypeId() ? object : CValueObjectMetaInfo<typename T::base_type>{}.upCastTo(base, metaTypeId);
}
virtual int compare(const void *lhs, const void *rhs) const override; // FIXME defined out-of-line in valueobject.h because it uses CValueObject
virtual void setPropertyByIndex(void *object, const CVariant &variant, const CPropertyIndex &index) const override
{
cast(object).setPropertyByIndex(variant, index);
}
virtual void propertyByIndex(const void *object, CVariant &o_variant, const BlackMisc::CPropertyIndex &index) const override
{
assign(o_variant, cast(object).propertyByIndex(index));
}
virtual QString propertyByIndexAsString(const void *object, const CPropertyIndex &index, bool i18n) const override
{
return cast(object).propertyByIndexAsString(index, i18n);
}
virtual bool equalsPropertyByIndex(const void *object, const CVariant &compareValue, const CPropertyIndex &index) const override
{
return cast(object).equalsPropertyByIndex(compareValue, index);
}
static const T &cast(const void *object) { return *static_cast<const T *>(object); }
static T &cast(void *object) { return *static_cast<T *>(object); }

View File

@@ -187,4 +187,35 @@ namespace BlackMisc
*this = fixQVariantFromDbusArgument(dbusVar.variant(), QMetaType::type(qPrintable(typeName)));
}
void CVariant::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index)
{
auto *meta = getValueObjectMetaInfo();
Q_ASSERT(meta);
meta->setPropertyByIndex(data(), variant, index);
}
CVariant CVariant::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
auto *meta = getValueObjectMetaInfo();
Q_ASSERT(meta);
CVariant result;
meta->propertyByIndex(data(), result, index);
return result;
}
QString CVariant::propertyByIndexAsString(const CPropertyIndex &index, bool i18n) const
{
auto *meta = getValueObjectMetaInfo();
Q_ASSERT(meta);
return meta->propertyByIndexAsString(data(), index, i18n);
}
bool CVariant::equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const
{
auto *meta = getValueObjectMetaInfo();
Q_ASSERT(meta);
return meta->equalsPropertyByIndex(data(), compareValue, index);
}
} // namespace

View File

@@ -197,6 +197,18 @@ namespace BlackMisc
//! \copydoc CValueObject::compareImpl
virtual int compareImpl(const CValueObject &other) const override;
//! \copydoc CValueObject::setPropertyByIndex
virtual void setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) override;
//! \copydoc CValueObject::propertyByIndex
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const override;
//! \copydoc CValueObject::propertyByIndexAsString
virtual QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const override;
//! \copydoc CValueObject::equalsPropertyByIndex
virtual bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const override;
private:
QVariant m_v;
@@ -234,6 +246,11 @@ namespace BlackMisc
return !(value == variant);
}
namespace Private
{
//! \private Needed so we can copy forward-declared CVariant.
inline void assign(CVariant &a, const CVariant &b) { a = b; }
}
} // namespace
Q_DECLARE_METATYPE(BlackMisc::CVariant)