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>
58 class GRANTLEE_CORE_EXPORT MetaType
64 typedef QVariant ( *LookupFunction )(
const QVariant &,
const QString & );
69 typedef QVariantList ( *ToVariantListFunction )(
const QVariant & );
74 static void registerLookUpOperator(
int id, LookupFunction f );
79 static void registerToVariantListOperator(
int id, ToVariantListFunction f );
84 static void internalLock();
89 static void internalUnlock();
94 static QVariant lookup(
const QVariant &
object,
const QString &property );
99 static QVariantList toVariantList(
const QVariant &obj );
104 static bool lookupAlreadyRegistered(
int id );
109 static bool toListAlreadyRegistered(
int id );
114 static inline int init();
119 static int initBuiltins() {
return init(); }
132 template<
typename RealType,
typename HandleAs>
135 static QVariant doLookUp(
const QVariant &
object,
const QString &property );
141 enum { Yes =
false };
145 struct IsQObjectStar<T*>
147 typedef int yes_type;
148 typedef char no_type;
150 static yes_type check(QObject*);
151 static no_type check(...);
152 enum { Yes =
sizeof(check(static_cast<T*>(0))) ==
sizeof(yes_type) };
155 template<
typename T,
bool>
158 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
160 typedef typename Grantlee::TypeAccessor<T> Accessor;
161 return Accessor::lookUp(
object.value<T>(), property );
166 struct LookupPointer<T, true>
168 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
170 typedef typename Grantlee::TypeAccessor<QObject*> Accessor;
171 return Accessor::lookUp(
object.value<T>(), property );
175 template<
typename RealType>
176 struct LookupTrait<RealType*, RealType*>
178 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
180 return LookupPointer<RealType*, IsQObjectStar<RealType*>::Yes>::doLookUp(
object, property);
184 template<
typename RealType,
typename HandleAs>
185 struct LookupTrait<RealType&, HandleAs&>
187 static QVariant doLookUp(
const QVariant &
object,
const QString &property )
189 typedef typename Grantlee::TypeAccessor<HandleAs&> Accessor;
190 return Accessor::lookUp( static_cast<HandleAs>(
object.value<RealType>() ), property );
194 template<
typename RealType,
typename HandleAs>
195 static int doRegister(
int id )
197 if ( MetaType::lookupAlreadyRegistered(
id ) )
200 QVariant ( *lf )(
const QVariant&,
const QString& ) = LookupTrait<RealType, HandleAs>::doLookUp;
202 MetaType::registerLookUpOperator(
id, reinterpret_cast<MetaType::LookupFunction>( lf ) );
210 template<
typename RealType,
typename HandleAs>
211 struct InternalRegisterType
214 const int id = qMetaTypeId<RealType>();
215 return doRegister<RealType&, HandleAs&>( id );
219 template<
typename RealType,
typename HandleAs>
220 struct InternalRegisterType<RealType*, HandleAs*>
223 const int id = qMetaTypeId<RealType*>();
224 return doRegister<RealType*, HandleAs*>( id );
228 template<
typename Container,
typename HandleAs>
229 int registerSequentialContainer()
231 const int id = InternalRegisterType<Container, HandleAs>::doReg();
233 if ( MetaType::toListAlreadyRegistered(
id ) )
236 QVariantList ( *tlf )(
const QVariant& ) = SequentialContainerAccessor<Container>::doToList;
237 MetaType::registerToVariantListOperator(
id, reinterpret_cast<MetaType::ToVariantListFunction>( tlf ) );
241 template<
typename Container>
242 int registerSequentialContainer()
244 return registerSequentialContainer<Container, Container>();
247 template<
typename Container,
typename HandleAs>
248 int registerAssociativeContainer()
250 const int id = InternalRegisterType<Container, HandleAs>::doReg();
252 if ( MetaType::toListAlreadyRegistered(
id ) )
255 QVariantList ( *tlf )(
const QVariant& ) = AssociativeContainerAccessor<Container>::doToList;
256 MetaType::registerToVariantListOperator(
id, reinterpret_cast<MetaType::ToVariantListFunction>( tlf ) );
260 template<
typename Container>
261 int registerAssociativeContainer()
263 return registerAssociativeContainer<Container, Container>();
275 template<
typename RealType,
int n>
276 struct RegisterTypeContainer
289 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_IF(Container, Type) \
290 Grantlee::RegisterTypeContainer<Container<Type>, QMetaTypeId2<Container<Type> >::Defined>::reg(); \
296 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, Key, Type) \
297 Grantlee::RegisterTypeContainer<Container<Key, Type>, QMetaTypeId2<Container<Key, Type> >::Defined>::reg(); \
316 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_IF(Container, Type) \
317 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, QString, Type) \
318 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint16, Type) \
319 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint32, Type) \
320 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, qint64, Type) \
321 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint16, Type) \
322 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint32, Type) \
323 GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER_KEY_IF(Container, quint64, Type) \
329 void registerContainers()
347 struct BuiltinRegister
349 void registerBuiltinContainers()
const
351 Grantlee::MetaType::internalLock();
353 registerContainers< bool >();
354 registerContainers< qint16 >();
355 registerContainers< qint32 >();
356 registerContainers< qint64 >();
357 registerContainers< quint16 >();
358 registerContainers< quint32 >();
359 registerContainers< quint64 >();
360 registerContainers< float >();
361 registerContainers< double >();
362 registerContainers< QString >();
363 registerContainers< QVariant >();
364 registerContainers< QDateTime >();
365 registerContainers< QObject* >();
367 registerSequentialContainer<QStringList, QList<QString> >();
368 Grantlee::MetaType::internalUnlock();
372 Q_GLOBAL_STATIC( BuiltinRegister, builtinRegister )
377 struct MetaTypeInitializer {
378 static inline int initialize()
380 static const BuiltinRegister *br = builtinRegister();
381 br->registerBuiltinContainers();
392 #define GRANTLEE_METATYPE_INITIALIZE static const int i = Grantlee::MetaTypeInitializer::initialize(); Q_UNUSED(i)
395 inline int MetaType::init()
437 template<
typename RealType,
typename HandleAs>
444 MetaType::internalLock();
446 const int id = InternalRegisterType<RealType, HandleAs>::doReg();
448 registerContainers<RealType>();
450 MetaType::internalUnlock();
462 template<
typename Type>
465 return registerMetaType<Type, Type>();
482 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER(Container) \
483 namespace Grantlee { \
484 template<typename T> \
485 struct RegisterTypeContainer<Container<T>, MoreMagic> \
489 const int id = registerSequentialContainer<Container<T> >(); \
490 registerContainers<Container<T> >(); \
501 #define GRANTLEE_REGISTER_ASSOCIATIVE_CONTAINER(Container) \
502 namespace Grantlee { \
503 template<typename T, typename U> \
504 struct RegisterTypeContainer<Container<T, U>, MoreMagic> \
508 const int id = registerAssociativeContainer<Container<T, U> >(); \
509 registerContainers<Container<T, U> >(); \
519 #define GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS(Container, As) \
520 namespace Grantlee { \
521 template<typename T> \
522 struct RegisterTypeContainer<Container<T>, MoreMagic> \
526 return registerSequentialContainer<Container<T>, As<T> >(); \
538 #define GRANTLEE_BEGIN_LOOKUP(Type) \
542 inline QVariant TypeAccessor<Type&>::lookUp( const Type &object, const QString &property ) \
550 #define GRANTLEE_BEGIN_LOOKUP_PTR(Type) \
554 inline QVariant TypeAccessor<Type*>::lookUp( const Type * const object, const QString &property ) \
562 #define GRANTLEE_END_LOOKUP \
569 GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS (QQueue, QList)
571 GRANTLEE_REGISTER_SEQUENTIAL_CONTAINER_AS (QStack, QVector)
583 #endif // #define GRANTLEE_METATYPE_H