Issue #77 Move mixin classes to separate files

By separating them from unrelated code, their dependents
can use them without depending on unrelated code, which
in turn helps to reduce cyclic dependencies.
This commit is contained in:
Mat Sutcliffe
2020-08-25 23:31:23 +01:00
parent 4a6d94b6d4
commit b80114213d
129 changed files with 1207 additions and 969 deletions

View File

@@ -13,13 +13,14 @@
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/compare.h"
#include "blackmisc/dbus.h"
#include "blackmisc/datastream.h"
#include "blackmisc/mixin/mixincompare.h"
#include "blackmisc/mixin/mixindbus.h"
#include "blackmisc/mixin/mixindatastream.h"
#include "blackmisc/inheritancetraits.h"
#include "blackmisc/json.h"
#include "blackmisc/mixin/mixinjson.h"
#include "blackmisc/range.h"
#include "blackmisc/stringutils.h"
#include "blackmisc/mixin/mixinstring.h"
#include "blackmisc/mixin/mixinmetatype.h"
#include "blackmisc/variantprivate.h"
#include <QDBusArgument>
@@ -39,83 +40,6 @@ namespace BlackMisc
class CPropertyIndex;
class CVariantList;
namespace Mixin
{
/*!
* CRTP class template from which a derived class can inherit common methods dealing with the metatype of the class.
*
* \see BLACKMISC_DECLARE_USING_MIXIN_METATYPE
*/
template <class Derived>
class MetaType
{
public:
//! Register metadata
static void registerMetadata()
{
Private::MetaTypeHelper<Derived>::maybeRegisterMetaType();
}
//! Returns the Qt meta type ID of this object
//! \remark for CVariant this returns the id of CVariant, not of the encapsulated object. valueVariant.userType()` returns metatype of the contained object
int getMetaTypeId() const
{
return Private::MetaTypeHelper<Derived>::maybeGetMetaTypeId();
}
//! Class name
QString getClassName() const
{
return QMetaType::typeName(getMetaTypeId());
}
//! Returns true if this object is an instance of the class with the given meta type ID, or one of its subclasses.
bool isA(int metaTypeId) const
{
if (metaTypeId == QMetaType::UnknownType) { return false; }
if (metaTypeId == getMetaTypeId()) { return true; }
return baseIsA(static_cast<const TMetaBaseOfT<Derived> *>(derived()), metaTypeId);
}
private:
const Derived *derived() const { return static_cast<const Derived *>(this); }
Derived *derived() { return static_cast<Derived *>(this); }
template <typename Base2> static bool baseIsA(const Base2 *base, int metaTypeId) { return base->isA(metaTypeId); }
static bool baseIsA(const void *, int) { return false; }
};
// *INDENT-OFF*
/*!
* When a derived class and a base class both inherit from Mixin::MetaType,
* the derived class uses this macro to disambiguate the inherited members.
*/
# define BLACKMISC_DECLARE_USING_MIXIN_METATYPE(DERIVED) \
using ::BlackMisc::Mixin::MetaType<DERIVED>::registerMetadata; \
using ::BlackMisc::Mixin::MetaType<DERIVED>::getMetaTypeId; \
using ::BlackMisc::Mixin::MetaType<DERIVED>::getClassName; \
using ::BlackMisc::Mixin::MetaType<DERIVED>::isA;
// *INDENT-ON*
} // Mixin
/*!
* 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.
*/
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);
}
/*!
* Wrapper around QVariant which provides transparent access to CValueObject methods
* of the contained object if it is registered with BlackMisc::registerMetaValueType.