Grantlee  5.1.0
templates/lib/metatype.h
Go to the documentation of this file.
00001 /*
00002   This file is part of the Grantlee template system.
00003 
00004   Copyright (c) 2010 Michael Jansen <kde@michael-jansen.biz>
00005   Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
00006 
00007   This library is free software; you can redistribute it and/or
00008   modify it under the terms of the GNU Lesser General Public
00009   License as published by the Free Software Foundation; either version
00010   2.1 of the Licence, or (at your option) any later version.
00011 
00012   This library is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   Lesser General Public License for more details.
00016 
00017   You should have received a copy of the GNU Lesser General Public
00018   License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 */
00021 
00022 #ifndef GRANTLEE_METATYPE_H
00023 #define GRANTLEE_METATYPE_H
00024 
00025 #include "grantlee_templates_export.h"
00026 
00027 #include "typeaccessor.h"
00028 
00029 #include <QtCore/QVariant>
00030 
00032 
00033 namespace Grantlee
00034 {
00035 
00037 
00038 #ifndef Q_QDOC
00039 
00052 class GRANTLEE_TEMPLATES_EXPORT MetaType
00053 {
00054 public:
00058   typedef QVariant (*LookupFunction)(const QVariant &, const QString &);
00059 
00063   static void registerLookUpOperator(int id, LookupFunction f);
00064 
00068   static void internalLock();
00069 
00073   static void internalUnlock();
00074 
00078   static QVariant lookup(const QVariant &object, const QString &property);
00079 
00083   static bool lookupAlreadyRegistered(int id);
00084 
00085 private:
00086   MetaType();
00087 };
00088 #endif
00089 
00090 namespace
00091 {
00092 
00093 /*
00094  * This is a helper to select an appropriate overload of indexAccess
00095  */
00096 template <typename RealType, typename HandleAs> struct LookupTrait {
00097   static QVariant doLookUp(const QVariant &object, const QString &property)
00098   {
00099     typedef typename Grantlee::TypeAccessor<RealType> Accessor;
00100     return Accessor::lookUp(object.value<RealType>(), property);
00101   }
00102 };
00103 
00104 template <typename RealType, typename HandleAs>
00105 struct LookupTrait<RealType &, HandleAs &> {
00106   static QVariant doLookUp(const QVariant &object, const QString &property)
00107   {
00108     typedef typename Grantlee::TypeAccessor<HandleAs &> Accessor;
00109     return Accessor::lookUp(object.value<HandleAs>(), property);
00110   }
00111 };
00112 
00113 template <typename RealType, typename HandleAs> static int doRegister(int id)
00114 {
00115   if (MetaType::lookupAlreadyRegistered(id))
00116     return id;
00117 
00118   QVariant (*lf)(const QVariant &, const QString &)
00119       = LookupTrait<RealType, HandleAs>::doLookUp;
00120 
00121   MetaType::registerLookUpOperator(
00122       id, reinterpret_cast<MetaType::LookupFunction>(lf));
00123 
00124   return id;
00125 }
00126 
00127 /*
00128  * Register a type so grantlee knows how to handle it.
00129  */
00130 template <typename RealType, typename HandleAs> struct InternalRegisterType {
00131   static int doReg()
00132   {
00133     const int id = qMetaTypeId<RealType>();
00134     return doRegister<RealType &, HandleAs &>(id);
00135   }
00136 };
00137 
00138 template <typename RealType, typename HandleAs>
00139 struct InternalRegisterType<RealType *, HandleAs *> {
00140   static int doReg()
00141   {
00142     const int id = qMetaTypeId<RealType *>();
00143     return doRegister<RealType *, HandleAs *>(id);
00144   }
00145 };
00146 }
00147 
00184 template <typename RealType, typename HandleAs> int registerMetaType()
00185 {
00186   MetaType::internalLock();
00187 
00188   const int id = InternalRegisterType<RealType, HandleAs>::doReg();
00189 
00190   MetaType::internalUnlock();
00191 
00192   return id;
00193 }
00194 
00195 #ifndef Q_QDOC
00196 
00202 template <typename Type> int registerMetaType()
00203 {
00204   return registerMetaType<Type, Type>();
00205 }
00206 
00207 #endif
00208 } // namespace Grantlee
00209 
00215 #define GRANTLEE_BEGIN_LOOKUP(Type)                                            \
00216   namespace Grantlee                                                           \
00217   {                                                                            \
00218   template <>                                                                  \
00219   inline QVariant TypeAccessor<Type &>::lookUp(const Type &object,             \
00220                                                const QString &property)        \
00221   {
00222 
00228 #define GRANTLEE_BEGIN_LOOKUP_PTR(Type)                                        \
00229   namespace Grantlee                                                           \
00230   {                                                                            \
00231   template <>                                                                  \
00232   inline QVariant TypeAccessor<Type *>::lookUp(const Type *const object,       \
00233                                                const QString &property)        \
00234   {
00235 
00241 #define GRANTLEE_END_LOOKUP                                                    \
00242   return QVariant();                                                           \
00243   }                                                                            \
00244   }
00245 
00246 #endif // #define GRANTLEE_METATYPE_H