Dataquay 0.8
ContainerBuilder.h
Go to the documentation of this file.
1/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3/*
4 Dataquay
5
6 A C++/Qt library for simple RDF datastore management.
7 Copyright 2009-2012 Chris Cannam.
8
9 Permission is hereby granted, free of charge, to any person
10 obtaining a copy of this software and associated documentation
11 files (the "Software"), to deal in the Software without
12 restriction, including without limitation the rights to use, copy,
13 modify, merge, publish, distribute, sublicense, and/or sell copies
14 of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 Except as contained in this notice, the name of Chris Cannam
29 shall not be used in advertising or otherwise to promote the sale,
30 use or other dealings in this Software without prior written
31 authorization.
32*/
33
34#ifndef DATAQUAY_CONTAINER_BUILDER_H
35#define DATAQUAY_CONTAINER_BUILDER_H
36
37#include <QHash>
38#include <QString>
39#include <QStringList>
40#include <QVariant>
41
42namespace Dataquay {
43
56{
57public:
62
73 SequenceKind, // e.g. list
74 SetKind // e.g. set
75 // perhaps also something for maps
76 };
77
94 template <typename T, typename Container>
95 void registerContainer(QString typeName, QString containerName,
96 ContainerKind kind) {
97 registerContainerExtractor<T, Container>
98 (typeName, containerName, kind);
99 }
100
107 bool canExtractContainer(QString containerName) {
108 return m_containerExtractors.contains(containerName);
109 }
110
117 bool canInjectContainer(QString containerName) {
118 return m_containerExtractors.contains(containerName);
119 }
120
127 QString getTypeNameForContainer(QString containerName) {
128 if (!canExtractContainer(containerName)) return QString();
129 return m_containerExtractors[containerName]->getTypeName();
130 }
131
138 ContainerKind getContainerKind(QString containerName) {
139 if (!canExtractContainer(containerName)) return UnknownKind;
140 return m_containerExtractors[containerName]->getKind();
141 }
142
148 QVariantList extractContainer(QString containerName, const QVariant &v) {
149 if (!canExtractContainer(containerName)) return QVariantList();
150 return m_containerExtractors[containerName]->extract(v);
151 }
152
159 QVariant injectContainer(QString containerName, const QVariantList &vl) {
160 if (!canInjectContainer(containerName)) return QVariant();
161 return m_containerExtractors[containerName]->inject(vl);
162 }
163
164private:
167 ("QString", "QStringList", SequenceKind);
168 }
169 ~ContainerBuilder() {
170 for (ContainerExtractorMap::iterator i = m_containerExtractors.begin();
171 i != m_containerExtractors.end(); ++i) {
172 delete *i;
173 }
174 }
175
176 template <typename T, typename Container>
177 void
178 registerContainerExtractor(QString typeName, QString containerName,
179 ContainerKind kind) {
180 m_containerExtractors[containerName] =
181 new ContainerExtractor<T, Container>(typeName, kind);
182 }
183
184 struct ContainerExtractorBase {
185 virtual ~ContainerExtractorBase() { }
186 virtual QVariantList extract(const QVariant &v) = 0;
187 virtual QVariant inject(const QVariantList &) = 0;
188 virtual QString getTypeName() const = 0;
189 virtual ContainerKind getKind() const = 0;
190 };
191
192 template <typename T, typename Container>
193 struct ContainerExtractor : public ContainerExtractorBase
194 {
195 ContainerExtractor(QString typeName, ContainerKind kind) :
196 m_typeName(typeName), m_kind(kind) { }
197
198 virtual QVariantList extract(const QVariant &v) {
199 Container tl = v.value<Container>();
200 QVariantList vl;
201 foreach (const T &t, tl) vl << QVariant::fromValue<T>(t);
202 return vl;
203 }
204 virtual QVariant inject(const QVariantList &vl) {
205 Container tl;
206 foreach (const QVariant &v, vl) tl << v.value<T>();
207 return QVariant::fromValue<Container>(tl);
208 }
209 virtual QString getTypeName() const {
210 return m_typeName;
211 }
212 virtual ContainerKind getKind() const {
213 return m_kind;
214 }
215
216 QString m_typeName;
217 ContainerKind m_kind;
218 };
219
220 typedef QHash<QString, ContainerExtractorBase *> ContainerExtractorMap;
221 ContainerExtractorMap m_containerExtractors;
222};
223
224}
225
226#endif
ContainerBuilder is a utility class which assists with storage of arbitrary container objects into va...
bool canInjectContainer(QString containerName)
Return true if the container named containerName can be injected into a variant.
QVariantList extractContainer(QString containerName, const QVariant &v)
Extract the named container type from the given variant object (which must hold that container type) ...
ContainerKind
ContainerKind describes the sort of behaviour a container displays with regard to ordering and struct...
QString getTypeNameForContainer(QString containerName)
Return the typeName that is associated with the given containerName.
ContainerKind getContainerKind(QString containerName)
Return the kind of the container with the given containerName.
bool canExtractContainer(QString containerName)
Return true if the container named containerName can be extracted from a variant.
static ContainerBuilder * getInstance()
Retrieve the single global instance of ContainerBuilder.
void registerContainer(QString typeName, QString containerName, ContainerKind kind)
Register Container as a container of kind ContainerKind holding type T.
QVariant injectContainer(QString containerName, const QVariantList &vl)
Inject the named container type into a new variant object.