refs #247 Created a facility to register our own custom metatype metadata.

This commit is contained in:
Mathew Sutcliffe
2014-11-12 19:03:47 +00:00
parent fc82270d68
commit c5b463fafb
4 changed files with 146 additions and 1 deletions

View File

@@ -17,6 +17,7 @@
#include "json.h"
#include "variant.h"
#include "blackmiscfreefunctions.h"
#include "valueobject_private.h"
#include "valueobject_policy.h"
#include <QtDBus/QDBusMetaType>
#include <QString>
@@ -56,6 +57,24 @@ namespace BlackMisc
};
}
/*!
* This registers the value type T with the BlackMisc meta type system,
* making it available for use with the extended feature set of BlackMisc::CVariant.
*
* The implementation (ab)uses the QMetaType converter function registration mechanism
* to store a type-erased representation of the set of operations supported by T.
* Unlike the singleton pattern, this approach means that CVariant can be used in plugins.
*/
template <typename T>
void registerMetaValueType()
{
if (QMetaType::hasRegisteredConverterFunction<T, Private::IValueObjectMetaInfo *>()) { return; }
auto converter = [](const T &) { static Private::CValueObjectMetaInfo<T> info; return &info; };
bool ok = QMetaType::registerConverter<T, Private::IValueObjectMetaInfo *>(converter);
Q_ASSERT(ok);
Q_UNUSED(ok);
}
/*!
* Base class for value types.
*/
@@ -194,6 +213,9 @@ namespace BlackMisc
static const CValueObject *fromQVariant(const QVariant &variant);
protected:
template <typename T>
friend struct Private::CValueObjectMetaInfo;
//! Default constructor.
CValueObject() = default;
@@ -238,6 +260,15 @@ namespace BlackMisc
virtual void parseFromString(const QString &) { qFatal("Not implemented"); }
};
//! \private FIXME defined out-of-line because it depends on CValueObject
template <typename T>
int Private::CValueObjectMetaInfo<T>::compare(const void *lhs, const void *rhs) const
{
// Casting to CValueObject here only because compareImpl is protected and CValueObjectMetaInfo is a friend of CValueObject.
// TODO: make compareImpl public (and typesafe), then this doesn't need to be defined out-of-line.
return static_cast<const CValueObject *>(lhs)->compareImpl(*static_cast<const CValueObject *>(rhs));
}
/*!
* Default policy classes for use by CValueObjectStdTuple.
*