Grantlee  0.5.1
typeaccessor.h
Go to the documentation of this file.
1 /*
2  This file is part of the Grantlee template system.
3 
4  Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #ifndef GRANTLEE_TYPEACCESSOR_H
22 #define GRANTLEE_TYPEACCESSOR_H
23 
24 #include "containeraccessor.h"
25 #include "grantlee_core_export.h"
26 
27 #include <QtCore/QLinkedList>
28 #include <QtCore/QSet>
29 #include <QtCore/QSharedPointer>
30 #include <QtCore/QVariant>
31 
32 #include <deque>
33 #include <list>
34 #include <vector>
35 
37 
38 namespace Grantlee
39 {
40 
41 #ifndef Q_QDOC
42 template <typename T>
43 struct TypeAccessor
44 {
45  static QVariant lookUp( const T object, const QString &property );
46 };
47 
48 template <typename T>
49 struct TypeAccessor<T*>
50 {
51  static QVariant lookUp( const T * const object, const QString &property );
52 };
53 
54 template <typename T>
55 struct TypeAccessor<T&>
56 {
57  static QVariant lookUp( const T &object, const QString &property );
58 };
59 #endif
60 
61 namespace
62 {
63 
64 template<typename Container>
65 struct SequentialContainerLookup
66 {
67  static QVariant doLookUp( const Container &container, const QString &property )
68  {
69  if ( property == QLatin1String( "size" ) || property == QLatin1String( "count" ) ) {
70  return QVariant::fromValue<int>( std::distance( container.begin(), container.end() ) );
71  }
72 
73  bool ok = false;
74  const size_t listIndex = ( size_t )property.toInt( &ok );
75 
76  if ( !ok || listIndex >= ( size_t )container.size() ) {
77  return QVariant();
78  }
79 
80  return QVariant::fromValue( container[listIndex] );
81  }
82 };
83 
84 template<typename Container>
85 QVariant doAssociativeContainerLookup( const Container &object, const QString &property )
86 {
87  {
88  typename Container::const_iterator it = Finder<Container>::find( object, property );
89  if ( it != object.end() )
90  return QVariant::fromValue( MappedValueGetter<Container>::get( it ) );
91  }
92  if ( property == QLatin1String( "size" ) || property == QLatin1String( "count" ) ) {
93  return QVariant::fromValue<int>( std::distance( object.begin(), object.end() ) );
94  }
95  if ( property == QLatin1String( "items" ) ) {
96  typename Container::const_iterator it = object.begin();
97  const typename Container::const_iterator end = object.end();
98  QVariantList list;
99  for ( ; it != end; ++it ) {
100  QVariantList nested;
101  nested.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) );
102  nested.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) );
103  list.push_back( nested );
104  }
105  return list;
106  }
107 
108  if ( property == QLatin1String( "keys" ) ) {
109  typename Container::const_iterator it = object.begin();
110  const typename Container::const_iterator end = object.end();
111  QVariantList list;
112  for ( ; it != end; ++it ) {
113  list.push_back( QVariant::fromValue( KeyGetter<Container>::get( it ) ) );
114  }
115  return list;
116  }
117 
118  if ( property == QLatin1String( "values" ) ) {
119  typename Container::const_iterator it = object.begin();
120  const typename Container::const_iterator end = object.end();
121  QVariantList list;
122  for ( ; it != end; ++it ) {
123  list.push_back( QVariant::fromValue( MappedValueGetter<Container>::get( it ) ) );
124  }
125  return list;
126  }
127 
128  return QVariant();
129 }
130 
131 }
132 
133 #ifndef Q_QDOC
134 template <>
135 QVariant GRANTLEE_CORE_EXPORT TypeAccessor<QObject*>::lookUp( const QObject * const object, const QString &property );
136 
140 QVariant GRANTLEE_CORE_EXPORT doQobjectLookUp( const QObject * const object, const QString& property );
141 #endif
142 }
143 
151 #define GRANTLEE_DISABLE_RANDOM_ACCESS(Container) \
152 namespace Grantlee { \
153 template<typename T> \
154 struct TypeAccessor<Container<T>&> \
155 { \
156  static QVariant lookUp( const Container<T> &c, const QString &p) \
157  { \
158  if ( p == QLatin1String( "size" ) \
159  || p == QLatin1String( "count" ) ) { \
160  return QVariant::fromValue<int>( \
161  std::distance( c.begin(), c.end() ) ); \
162  } \
163  return QVariant(); \
164  } \
165 }; \
166 } \
167 
168 
173 #define GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(Container) \
174 namespace Grantlee { \
175 template<typename T> \
176 struct TypeAccessor<Container<T>&> \
177 { \
178  static QVariant lookUp( const Container<T> &c, const QString &property ) \
179  { \
180  return SequentialContainerLookup<Container<T> >::doLookUp( c, property ); \
181  } \
182 }; \
183 } \
184 
185 
192 #define GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(Container) \
193 namespace Grantlee { \
194 template<typename T, typename U> \
195 struct TypeAccessor<Container<T, U>&> \
196 { \
197  static QVariant lookUp( const Container<T, U> &c, const QString &property ) \
198  { \
199  return doAssociativeContainerLookup( c, property ); \
200  } \
201 }; \
202 } \
203 
204 
209 #define GRANTLEE_SMART_PTR_ACCESSOR(SmartPointer) \
210 namespace Grantlee { \
211 template<typename T> \
212 struct TypeAccessor<SmartPointer<T>&> \
213 { \
214  static QVariant lookUp( const SmartPointer<T> &object, const QString &property ) \
215  { \
216  return doQobjectLookUp( object.operator->(), property ); \
217  } \
218 }; \
219 } \
220 
223 
226 
230 
234 
235 GRANTLEE_SMART_PTR_ACCESSOR(QSharedPointer)
236 
237 #endif
#define GRANTLEE_ASSOCIATIVE_TYPE_CONTAINER_ACCESSOR(Container)
Definition: typeaccessor.h:192
static Container::key_type get(const typename Container::const_iterator it)
#define GRANTLEE_DISABLE_RANDOM_ACCESS(Container)
Definition: typeaccessor.h:151
#define GRANTLEE_SEQUENTIAL_TYPE_CONTAINER_ACCESSOR(Container)
Definition: typeaccessor.h:173
static Container::mapped_type get(const typename Container::const_iterator it)
#define GRANTLEE_SMART_PTR_ACCESSOR(SmartPointer)
Definition: typeaccessor.h:209
The Grantlee namespace holds all public Grantlee API.
Definition: Mainpage.dox:7