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 CONTAINERACCESSOR_H 00022 #define CONTAINERACCESSOR_H 00023 00024 #include <QtCore/QVariant> 00025 00026 #include <map> 00027 00028 namespace Grantlee 00029 { 00030 00032 00035 template<typename Container_> 00036 struct Getter 00037 { 00041 typedef Container_ Container; 00042 }; 00043 00045 00052 template<typename Container> 00053 struct KeyGetter : public Getter<Container> 00054 { 00058 static typename Container::key_type get( const typename Container::const_iterator it ) { 00059 return it.key(); 00060 } 00061 }; 00062 00064 00071 template<typename Container> 00072 struct MappedValueGetter : public Getter<Container> 00073 { 00077 static typename Container::mapped_type get( const typename Container::const_iterator it ) { 00078 return *it; 00079 } 00080 }; 00081 00082 #ifndef Q_QDOC 00083 template<typename T, typename U> 00084 struct KeyGetter<std::map<T, U> > : public Getter<std::map<T, U> > 00085 { 00086 static T get( typename std::map<T, U>::const_iterator it ) { 00087 return it->first; 00088 } 00089 }; 00090 00091 template<typename T, typename U> 00092 struct MappedValueGetter<std::map<T, U> > : public Getter<std::map<T, U> > 00093 { 00094 static U get( typename std::map<T, U>::const_iterator it ) { 00095 return it->second; 00096 } 00097 }; 00098 00099 template<typename Container> 00100 struct ValueGetter : public Getter<Container> 00101 { 00102 static typename Container::value_type get( const typename Container::const_iterator it ) { 00103 return *it; 00104 } 00105 }; 00106 00107 template<typename Container, typename T = typename Container::key_type> 00108 struct Finder 00109 { 00110 static typename Container::const_iterator find( const Container &container, const QString &nextPart ) 00111 { 00112 { 00113 // Compile error if key_type is not a number. 00114 static const QString s = QString::number( T() ); 00115 Q_UNUSED( s ) 00116 } 00117 00118 QVariant v = nextPart; 00119 if ( !v.canConvert<typename Container::key_type>() || !v.convert( QVariant::Double ) ) 00120 return container.end(); 00121 typename Container::key_type key = v.value<typename Container::key_type>(); 00122 return container.find( key ); 00123 } 00124 }; 00125 00126 template<typename Container> 00127 struct Finder<Container, QString> 00128 { 00129 static typename Container::const_iterator find( const Container &container, const QString &nextPart ) 00130 { 00131 return container.find( nextPart ); 00132 } 00133 }; 00134 #endif 00135 00136 namespace { 00137 00138 template<typename Getter> 00139 QVariantList getList( const QVariant &obj ) 00140 { 00141 const typename Getter::Container c = obj.value<typename Getter::Container>(); 00142 typename Getter::Container::const_iterator it = c.begin(); 00143 const typename Getter::Container::const_iterator end = c.end(); 00144 QVariantList list; 00145 for ( ; it != end; ++it ) { 00146 list << QVariant::fromValue( Getter::get( it ) ); 00147 } 00148 return list; 00149 } 00150 00151 template<typename Container> 00152 struct SequentialContainerAccessor 00153 { 00154 static QVariantList doToList( const QVariant &obj ) 00155 { 00156 return getList<ValueGetter<Container> >( obj ); 00157 } 00158 }; 00159 00160 template<> 00161 struct SequentialContainerAccessor<QVariantList> 00162 { 00163 static QVariantList doToList( const QVariant &obj ) 00164 { 00165 return obj.toList(); 00166 } 00167 }; 00168 00169 template<typename Container> 00170 struct AssociativeContainerAccessor 00171 { 00172 static QVariantList doToList( const QVariant &obj ) 00173 { 00174 return getList<KeyGetter<Container> >( obj ); 00175 } 00176 }; 00177 00178 } 00179 00180 } 00181 00182 #endif