Issue #15 Added CVariant::matches()

If the contained object type has a matches() method, CVariant::matches()
will call that method and return its result.
(This is a utility to allow using CVariant to represent an event subscription.)
This commit is contained in:
Mat Sutcliffe
2019-02-26 01:51:21 +00:00
parent 8de217fbab
commit 073f1549a2
7 changed files with 75 additions and 1 deletions

View File

@@ -193,7 +193,8 @@ namespace BlackMisc
bool matchesVariant(const CVariant &value) const;
//! True if this map matches the value
template <typename T> bool matches(const T &value) const { return matchesVariant(CVariant::from(value)); }
template <typename T, typename = std::enable_if_t<!std::is_same<T, CVariant>::value>>
bool matches(const T &value) const { return matchesVariant(CVariant::from(value)); }
//! Map
const QMap<CPropertyIndex, CVariant> &map() const { return m_values; }

View File

@@ -533,6 +533,26 @@ namespace BlackMisc
return toIcon().toPixmap();
}
bool CVariant::matches(const CVariant &value) const
{
if (! isValid()) { return false; }
auto *meta = getValueObjectMetaInfo();
if (! meta)
{
CLogMessage(this).warning(u"Invalid type for CVariant::matches: %1") << typeName();
return false;
}
try
{
return meta->matches(data(), value);
}
catch (const Private::CVariantException &ex)
{
CLogMessage(this).debug() << ex.what();
return false;
}
}
QVariant fixQVariantFromDbusArgument(const QVariant &variant, int localUserType, const QString &typeName)
{
if (localUserType == static_cast<int>(QVariant::Invalid))

View File

@@ -343,6 +343,9 @@ namespace BlackMisc
//! \copydoc BlackMisc::Mixin::Icon::toIcon
CIcon toIcon() const;
//! If this is an event subscription, return true if it matches the given event.
bool matches(const CVariant &event) const;
private:
QVariant m_v;

View File

@@ -36,4 +36,9 @@ namespace BlackMisc
QMetaType::registerConverter<CVariantList, QVector<CVariant>>([](const CVariantList &list) { return list.toVector(); });
QMetaType::registerConverter<QVector<CVariant>, CVariantList>([](const QVector<CVariant> &list) { return CSequence(list); });
}
bool CVariantList::matches(const CVariant &event) const
{
return containsBy([ & ](const CVariant &pattern) { return pattern.matches(event); });
}
} // ns

View File

@@ -59,6 +59,9 @@ namespace BlackMisc
//! \copydoc BlackMisc::CValueObject::registerMetadata
static void registerMetadata();
//! True if any element of the list matches the given event.
bool matches(const CVariant &event) const;
};
}

View File

@@ -59,6 +59,7 @@ namespace BlackMisc
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;
virtual bool matches(const void *object, const CVariant &value) const = 0;
virtual void toIcon(const void *object, CIcon &o_icon) const = 0;
};
@@ -141,6 +142,11 @@ namespace BlackMisc
static void toIcon(const T &object, CIcon &o_icon, std::enable_if_t < ! std::is_same<T, CVariant>::value, decltype(static_cast<void>(object.toIcon()), 0) >) { assign(o_icon, object.toIcon()); }
template <typename T>
static void toIcon(const T &object, CIcon &, ...) { throw CVariantException(object, "toIcon"); }
template <typename T>
static bool matches(const T &object, const CVariant &value, decltype(static_cast<void>(object.matches(value)), 0)) { return object.matches(value); }
template <typename T>
static bool matches(const T &object, const CVariant &, ...) { throw CVariantException(object, "matches"); }
};
//! \private Implementation of IValueObjectMetaInfo representing the set of operations supported by T.
@@ -208,6 +214,10 @@ namespace BlackMisc
{
CValueObjectMetaInfoHelper::toIcon(cast(object), o_icon, 0);
}
virtual bool matches(const void *object, const CVariant &value) const override
{
return CValueObjectMetaInfoHelper::matches(cast(object), value, 0);
}
static const T &cast(const void *object) { return *static_cast<const T *>(object); }
static T &cast(void *object) { return *static_cast<T *>(object); }