Grantlee
0.5.1
|
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 if ( property == QLatin1String( "size" ) || property == QLatin1String( "count" ) ) { 00070 return QVariant::fromValue<int>( std::distance( container.begin(), container.end() ) ); 00071 } 00072 00073 bool ok = false; 00074 const size_t listIndex = ( size_t )property.toInt( &ok ); 00075 00076 if ( !ok || listIndex >= ( size_t )container.size() ) { 00077 return QVariant(); 00078 } 00079 00080 return QVariant::fromValue( container[listIndex] ); 00081 } 00082 }; 00083 00084 template<typename Container> 00085 QVariant doAssociativeContainerLookup( const Container &object, const QString &property ) 00086 { 00087 { 00088 typename Container::const_iterator it = Finder<Container>::find( object, property ); 00089 if ( it != object.end() ) 00090 return QVariant::fromValue( MappedValueGetter<Container>::get( it ) ); 00091 } 00092 if ( property == QLatin1String( "size" ) || property == QLatin1String( "count" ) ) { 00093 return QVariant::fromValue<int>( std::distance( object.begin(), object.end() ) ); 00094 } 00095 if ( property == QLatin1String( "items" ) ) { 00096 typename Container::const_iterator it = object.begin(); 00097 const typename Container::const_iterator end = object.end(); 00098 QVariantList list; 00099 for ( ; it != end; ++it ) { 00100 QVariantList nested; 00101 nested.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) ); 00102 nested.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) ); 00103 list.push_back( nested ); 00104 } 00105 return list; 00106 } 00107 00108 if ( property == QLatin1String( "keys" ) ) { 00109 typename Container::const_iterator it = object.begin(); 00110 const typename Container::const_iterator end = object.end(); 00111 QVariantList list; 00112 for ( ; it != end; ++it ) { 00113 list.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) ); 00114 } 00115 return list; 00116 } 00117 00118 if ( property == QLatin1String( "values" ) ) { 00119 typename Container::const_iterator it = object.begin(); 00120 const typename Container::const_iterator end = object.end(); 00121 QVariantList list; 00122 for ( ; it != end; ++it ) { 00123 list.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) ); 00124 } 00125 return list; 00126 } 00127 00128 return QVariant(); 00129 } 00130 00131 } 00132 00133 #ifndef Q_QDOC 00134 template <> 00135 QVariant GRANTLEE_CORE_EXPORT TypeAccessor<QObject*>::lookUp( const QObject * const object, const QString &property ); 00136 00140 QVariant GRANTLEE_CORE_EXPORT doQobjectLookUp( const QObject * const object, const QString& property ); 00141 #endif 00142 } 00143 00151 #define GRANTLEE_DISABLE_RANDOM_ACCESS(Container) \ 00152 namespace Grantlee { \ 00153 template<typename T> \ 00154 struct TypeAccessor<Container<T>&> \ 00155 { \ 00156 static QVariant lookUp( const Container<T> &c, const QString &p) \ 00157 { \ 00158 if ( p == QLatin1String( "size" ) \ 00159 || p == QLatin1String( "count" ) ) { \ 00160 return QVariant::fromValue<int>( \ 00161 std::distance( c.begin(), c.end() ) ); \ 00162 } \ 00163 return QVariant(); \ 00164 } \ 00165 }; \ 00166 } \ 00167 00168 00173 #define GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(Container) \ 00174 namespace Grantlee { \ 00175 template<typename T> \ 00176 struct TypeAccessor<Container<T>&> \ 00177 { \ 00178 static QVariant lookUp( const Container<T> &c, const QString &property ) \ 00179 { \ 00180 return SequentialContainerLookup<Container<T> >::doLookUp( c, property ); \ 00181 } \ 00182 }; \ 00183 } \ 00184 00185 00192 #define GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(Container) \ 00193 namespace Grantlee { \ 00194 template<typename T, typename U> \ 00195 struct TypeAccessor<Container<T, U>&> \ 00196 { \ 00197 static QVariant lookUp( const Container<T, U> &c, const QString &property ) \ 00198 { \ 00199 return doAssociativeContainerLookup( c, property ); \ 00200 } \ 00201 }; \ 00202 } \ 00203 00204 00209 #define GRANTLEE_SMART_PTR_ACCESSOR(SmartPointer) \ 00210 namespace Grantlee { \ 00211 template<typename T> \ 00212 struct TypeAccessor<SmartPointer<T>&> \ 00213 { \ 00214 static QVariant lookUp( const SmartPointer<T> &object, const QString &property ) \ 00215 { \ 00216 return doQobjectLookUp( object.operator->(), property ); \ 00217 } \ 00218 }; \ 00219 } \ 00220 00221 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(QList) 00222 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(QVector) 00223 00224 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(QHash) 00225 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(QMap) 00226 00227 GRANTLEE_DISABLE_RANDOM_ACCESS(QSet) 00228 GRANTLEE_DISABLE_RANDOM_ACCESS(QLinkedList) 00229 GRANTLEE_DISABLE_RANDOM_ACCESS(std::list) 00230 00231 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR (std::deque) 00232 GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR (std::vector) 00233 GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR (std::map) 00234 00235 GRANTLEE_SMART_PTR_ACCESSOR(QSharedPointer) 00236 00237 #endif