22 #ifndef GRANTLEE_METATYPE_H
23 #define GRANTLEE_METATYPE_H
25 #include "grantlee_core_export.h"
29 #include <QtCore/QVariant>
30 #include <QtCore/QStringList>
31 #include <QtCore/QStack>
32 #include <QtCore/QQueue>
33 #include <QtCore/QDateTime>
59 class GRANTLEE_CORE_EXPORT MetaType
65 typedef QVariant ( *LookupFunction )(
const QVariant &,
const QString & );
70 typedef QVariantList ( *ToVariantListFunction )(
const QVariant & );
75 static void registerLookUpOperator(
int id, LookupFunction f );
80 static void registerToVariantListOperator(
int id, ToVariantListFunction f );
85 static void internalLock();
90 static void internalUnlock();
95 static QVariant lookup(
const QVariant &
object,
const QString &property );
100 static QVariantList toVariantList(
const QVariant &obj );
105 static bool lookupAlreadyRegistered(
int id );
110 static bool toListAlreadyRegistered(
int id );
115 static inline int init();
120 static int initBuiltins() {
return init(); }
133 template<
typename RealType,
typename HandleAs>
136 static QVariant doLookUp(
const QVariant &
object,
const QString &property );
142 enum { Yes =
false };
146 struct IsQObjectStar<T*>
148 typedef int yes_type;
149 typedef char no_type;
151 static yes_type check(QObject*);
152 static no_type check(...);
153 enum { Yes =
sizeof(check(static_cast<T*>(0))) ==
sizeof(yes_type) };
156 template<
typename T,
bool>
159 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
161 typedef typename Grantlee::TypeAccessor<T> Accessor;
162 return Accessor::lookUp(
object.value<T>(), property );
167 struct LookupPointer<T, true>
169 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
171 typedef typename Grantlee::TypeAccessor<QObject*> Accessor;
172 return Accessor::lookUp(
object.value<T>(), property );
176 template<
typename RealType>
177 struct LookupTrait<RealType*, RealType*>
179 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
181 return LookupPointer<RealType*, IsQObjectStar<RealType*>::Yes>::doLookUp(
object, property);
185 template<
typename RealType,
typename HandleAs>
186 struct LookupTrait<RealType&, HandleAs&>
188 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
190 typedef typename Grantlee::TypeAccessor<HandleAs&> Accessor;
191 return Accessor::lookUp( static_cast<HandleAs>(
object.value<RealType>() ), property );
195 template<
typename RealType,
typename HandleAs>
196 static int doRegister(
int id )
198 if ( MetaType::lookupAlreadyRegistered(
id ) )
201 QVariant ( *lf )(
const QVariant&,
const QString& ) = LookupTrait<RealType, HandleAs>::doLookUp;
203 MetaType::registerLookUpOperator(
id, reinterpret_cast<MetaType::LookupFunction>( lf ) );
211 template<
typename RealType,
typename HandleAs>
212 struct InternalRegisterType
215 const int id = qMetaTypeId<RealType>();
216 return doRegister<RealType&, HandleAs&>( id );
220 template<
typename RealType,
typename HandleAs>
221 struct InternalRegisterType<RealType*, HandleAs*>
224 const int id = qMetaTypeId<RealType*>();
225 return doRegister<RealType*, HandleAs*>( id );
229 template<
typename Container,
typename HandleAs>
230 int registerSequentialContainer()
232 const int id = InternalRegisterType<Container, HandleAs>::doReg();
234 if ( MetaType::toListAlreadyRegistered(
id ) )
237 QVariantList ( *tlf )(
const QVariant& ) = SequentialContainerAccessor<Container>::doToList;
238 MetaType::registerToVariantListOperator(
id, reinterpret_cast<MetaType::ToVariantListFunction>( tlf ) );
242 template<
typename Container>
243 int registerSequentialContainer()
245 return registerSequentialContainer<Container, Container>();
248 template<
typename Container,
typename HandleAs>
249 int registerAssociativeContainer()
251 const int id = InternalRegisterType<Container, HandleAs>::doReg();
253 if ( MetaType::toListAlreadyRegistered(
id ) )
256 QVariantList ( *tlf )(
const QVariant& ) = AssociativeContainerAccessor<Container>::doToList;
257 MetaType::registerToVariantListOperator(
id, reinterpret_cast<MetaType::ToVariantListFunction>( tlf ) );
261 template<
typename Container>
262 int registerAssociativeContainer()
264 return registerAssociativeContainer<Container, Container>();
276 template<
typename RealType,
int n>
277 struct RegisterTypeContainer
290 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_IF(Container, Type) \
291 Grantlee::RegisterTypeContainer<Container<Type>, QMetaTypeId2<Container<Type> >::Defined>::reg(); \
297 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, Key, Type) \
298 Grantlee::RegisterTypeContainer<Container<Key, Type>, QMetaTypeId2<Container<Key, Type> >::Defined>::reg(); \
317 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_IF(Container, Type) \
318 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, QString, Type) \
319 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint16, Type) \
320 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint32, Type) \
321 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint64, Type) \
322 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint16, Type) \
323 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint32, Type) \
324 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint64, Type) \
330 void registerContainers()
348 struct BuiltinRegister
350 void registerBuiltinContainers()
const
352 Grantlee::MetaType::internalLock();
354 registerContainers< bool >();
355 registerContainers< qint16 >();
356 registerContainers< qint32 >();
357 registerContainers< qint64 >();
358 registerContainers< quint16 >();
359 registerContainers< quint32 >();
360 registerContainers< quint64 >();
361 registerContainers< float >();
362 registerContainers< double >();
363 registerContainers< QString >();
364 registerContainers< QVariant >();
365 registerContainers< QDateTime >();
366 registerContainers< QObject* >();
368 registerSequentialContainer<QStringList, QList<QString> >();
369 Grantlee::MetaType::internalUnlock();
373 Q_GLOBAL_STATIC( BuiltinRegister, builtinRegister )
378 struct MetaTypeInitializer {
379 static inline int initialize()
381 static const BuiltinRegister *br = builtinRegister();
382 br->registerBuiltinContainers();
393 #define GRANTLEE_METATYPE_INITIALIZE static const int i = Grantlee::MetaTypeInitializer::initialize(); Q_UNUSED(i)
396 inline int MetaType::init()
438 template<
typename RealType,
typename HandleAs>
445 MetaType::internalLock();
447 const int id = InternalRegisterType<RealType, HandleAs>::doReg();
449 registerContainers<RealType>();
451 MetaType::internalUnlock();
463 template<
typename Type>
466 return registerMetaType<Type, Type>();
483 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER(Container) \
484 namespace Grantlee { \
485 template<typename T> \
486 struct RegisterTypeContainer<Container<T>, MoreMagic> \
490 const int id = registerSequentialContainer<Container<T> >(); \
491 registerContainers<Container<T> >(); \
502 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER(Container) \
503 namespace Grantlee { \
504 template<typename T, typename U> \
505 struct RegisterTypeContainer<Container<T, U>, MoreMagic> \
509 const int id = registerAssociativeContainer<Container<T, U> >(); \
510 registerContainers<Container<T, U> >(); \
520 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS(Container, As) \
521 namespace Grantlee { \
522 template<typename T> \
523 struct RegisterTypeContainer<Container<T>, MoreMagic> \
527 return registerSequentialContainer<Container<T>, As<T> >(); \
539 #define GRANTLEE_BEGIN_LOOKUP(Type) \
543 inline QVariant TypeAccessor<Type&>::lookUp( const Type &object, const QString &property ) \
551 #define GRANTLEE_BEGIN_LOOKUP_PTR(Type) \
555 inline QVariant TypeAccessor<Type*>::lookUp( const Type * const object, const QString &property ) \
563 #define GRANTLEE_END_LOOKUP \
570 GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS (QQueue, QList)
572 GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS (QStack, QVector)
584 #endif // #define GRANTLEE_METATYPE_H
int registerMetaType()
Registers the type RealType with the metatype system.