Grantlee 0.1.9
templates/lib/typeaccessor.h
Go to the documentation of this file.
00001 /*
00002   This file is part of the Grantlee template system.
00003 
00004   Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
00005 
00006   This library is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Lesser General Public
00008   License as published by the Free Software Foundation; either version
00009   2.1 of the Licence, or (at your option) any later version.
00010 
00011   This library is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Lesser General Public License for more details.
00015 
00016   You should have received a copy of the GNU Lesser General Public
00017   License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 */
00020 
00021 #ifndef GRANTLEE_TYPEACCESSOR_H
00022 #define GRANTLEE_TYPEACCESSOR_H
00023 
00024 #include "containeraccessor.h"
00025 #include "grantlee_core_export.h"
00026 
00027 #include <QtCore/QLinkedList>
00028 #include <QtCore/QSet>
00029 #include <QtCore/QSharedPointer>
00030 #include <QtCore/QVariant>
00031 
00032 #include <deque>
00033 #include <list>
00034 #include <vector>
00035 
00037 
00038 namespace Grantlee
00039 {
00040 
00041 #ifndef Q_QDOC
00042 template <typename T>
00043 struct TypeAccessor
00044 {
00045   static QVariant lookUp( const T object, const QString &property );
00046 };
00047 
00048 template <typename T>
00049 struct TypeAccessor<T*>
00050 {
00051   static QVariant lookUp( const T * const object, const QString &property );
00052 };
00053 
00054 template <typename T>
00055 struct TypeAccessor<T&>
00056 {
00057   static QVariant lookUp( const T &object, const QString &property );
00058 };
00059 #endif
00060 
00061 namespace
00062 {
00063 
00064 template<typename Container>
00065 struct SequentialContainerLookup
00066 {
00067   static QVariant doLookUp( const Container &container, const QString &property )
00068   {
00069     bool ok = false;
00070     const size_t listIndex = ( size_t )property.toInt( &ok );
00071 
00072     if ( !ok || listIndex >= ( size_t )container.size() ) {
00073       return QVariant();
00074     }
00075 
00076     return QVariant::fromValue( container[listIndex] );
00077   }
00078 };
00079 
00080 template<typename Container>
00081 QVariant doAssociativeContainerLookup( const Container &object, const QString &property )
00082 {
00083   {
00084     typename Container::const_iterator it = Finder<Container>::find( object, property );
00085     if ( it != object.end() )
00086       return QVariant::fromValue( MappedValueGetter<Container>::get( it ) );
00087   }
00088   if ( property == QLatin1String( "items" ) ) {
00089     typename Container::const_iterator it = object.begin();
00090     const typename Container::const_iterator end = object.end();
00091     QVariantList list;
00092     for ( ; it != end; ++it ) {
00093       QVariantList nested;
00094       nested.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) );
00095       nested.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) );
00096       list.push_back( nested );
00097     }
00098     return list;
00099   }
00100 
00101   if ( property == QLatin1String( "keys" ) ) {
00102     typename Container::const_iterator it = object.begin();
00103     const typename Container::const_iterator end = object.end();
00104     QVariantList list;
00105     for ( ; it != end; ++it ) {
00106       list.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) );
00107     }
00108     return list;
00109   }
00110 
00111   if ( property == QLatin1String( "values" ) ) {
00112     typename Container::const_iterator it = object.begin();
00113     const typename Container::const_iterator end = object.end();
00114     QVariantList list;
00115     for ( ; it != end; ++it ) {
00116       list.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) );
00117     }
00118     return list;
00119   }
00120 
00121   return QVariant();
00122 }
00123 
00124 }
00125 
00126 #ifndef Q_QDOC
00127 template <>
00128 QVariant GRANTLEE_CORE_EXPORT TypeAccessor<QObject*>::lookUp( const QObject * const object, const QString &property );
00129 
00133 QVariant GRANTLEE_CORE_EXPORT doQobjectLookUp( const QObject * const object, const QString& property );
00134 #endif
00135 }
00136 
00144 #define GRANTLEE_DISABLE_RANDOM_ACCESS(Container)                     \
00145 namespace Grantlee {                                                  \
00146 template<typename T>                                                  \
00147 struct TypeAccessor<Container<T>&>                                    \
00148 {                                                                     \
00149   static QVariant lookUp( const Container<T> &, const QString &)      \
00150   {                                                                   \
00151     return QVariant();                                                \
00152   }                                                                   \
00153 };                                                                    \
00154 }                                                                     \
00155 
00156 
00161 #define GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(Container)                          \
00162 namespace Grantlee {                                                                    \
00163 template<typename T>                                                                    \
00164 struct TypeAccessor<Container<T>&>                                                      \
00165 {                                                                                       \
00166   static QVariant lookUp( const Container<T> &c, const QString &property )              \
00167   {                                                                                     \
00168     return SequentialContainerLookup<Container<T> >::doLookUp( c, property );           \
00169   }                                                                                     \
00170 };                                                                                      \
00171 }                                                                                       \
00172 
00173 
00180 #define GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(Container)                    \
00181 namespace Grantlee {                                                               \
00182 template<typename T, typename U>                                                   \
00183 struct TypeAccessor<Container<T, U>&>                                              \
00184 {                                                                                  \
00185   static QVariant lookUp( const Container<T, U> &c, const QString &property )      \
00186   {                                                                                \
00187     return doAssociativeContainerLookup( c, property );                            \
00188   }                                                                                \
00189 };                                                                                 \
00190 }                                                                                  \
00191 
00192 
00197 #define GRANTLEE_SMART_PTR_ACCESSOR(SmartPointer)                                  \
00198 namespace Grantlee {                                                               \
00199 template<typename T>                                                               \
00200 struct TypeAccessor<SmartPointer<T>&>                                              \
00201 {                                                                                  \
00202   static QVariant lookUp( const SmartPointer<T> &object, const QString &property ) \
00203   {                                                                                \
00204     return doQobjectLookUp( object.operator->(), property );                       \
00205   }                                                                                \
00206 };                                                                                 \
00207 }                                                                                  \
00208 
00209 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(QList)
00210 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(QVector)
00211 
00212 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(QHash)
00213 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(QMap)
00214 
00215 GRANTLEE_DISABLE_RANDOM_ACCESS(QSet)
00216 GRANTLEE_DISABLE_RANDOM_ACCESS(QLinkedList)
00217 GRANTLEE_DISABLE_RANDOM_ACCESS(std::list)
00218 
00219 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR  (std::deque)
00220 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR  (std::vector)
00221 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR (std::map)
00222 
00223 GRANTLEE_SMART_PTR_ACCESSOR(QSharedPointer)
00224 
00225 #endif