Grantlee
0.2.0
|
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