]> git.tdb.fi Git - libs/datafile.git/blob - source/loaderaction.h
03a9da7bcc1aa8fc33823f404a0426f704aaeaed
[libs/datafile.git] / source / loaderaction.h
1 /* $Id$
2
3 This file is part of libmspdatafile
4 Copyright © 2008, 2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #ifndef MSP_DATAFILE_LOADERACTION_H_
9 #define MSP_DATAFILE_LOADERACTION_H_
10
11 #include "except.h"
12 #include "statement.h"
13
14 namespace Msp {
15 namespace DataFile {
16
17 class Loader;
18
19 /**
20 Base class for loader actions.
21 */
22 class LoaderAction
23 {
24 protected:
25         LoaderAction() { }
26 public:
27         virtual ~LoaderAction() { }
28
29         /** Called to process a statement. */
30         virtual void execute(Loader &, const Statement &) const = 0;
31
32         virtual std::string get_signature() const = 0;
33 };
34
35
36 /**
37 Loads a statement by calling a function that takes no arguments.
38 */
39 template<typename L>
40 class LoaderFunc0: public LoaderAction
41 {
42 private:
43         typedef void (L::*FuncType)();
44
45         FuncType func;
46
47 public:
48         LoaderFunc0(FuncType f): func(f) { }
49
50         virtual void execute(Loader &l, const Statement &) const
51         {
52                 (dynamic_cast<L &>(l).*func)();
53         };
54
55         virtual std::string get_signature() const
56         { return std::string(); }
57 };
58
59
60 /**
61 Loads a statement by calling a function that takes one argument.
62 */
63 template<typename L, typename A0>
64 class LoaderFunc1: public LoaderAction
65 {
66 private:
67         typedef void (L::*FuncType)(A0);
68
69         FuncType func;
70
71 public:
72         LoaderFunc1(FuncType f): func(f) { }
73
74         virtual void execute(Loader &l, const Statement &st) const
75         {
76                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>());
77         }
78
79         virtual std::string get_signature() const
80         { return std::string(1, TypeInfo<A0>::signature); }
81 };
82
83
84 /**
85 Loads a statement by calling a function that takes an array of values.
86 */
87 template<typename L, typename A0>
88 class LoaderFunc1<L, const std::vector<A0> &>: public LoaderAction
89 {
90 private:
91         typedef void (L::*FuncType)(const std::vector<A0> &);
92
93         FuncType func;
94
95 public:
96         LoaderFunc1(FuncType f): func(f) { }
97
98         virtual void execute(Loader &l, const Statement &st) const
99         {
100                 std::vector<A0> values;
101                 values.reserve(st.args.size());
102                 for(Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
103                         values.push_back(i->get<A0>());
104                 (dynamic_cast<L &>(l).*func)(values);
105         }
106
107         virtual std::string get_signature() const
108         {
109                 std::string result;
110                 result += TypeInfo<A0>::signature;
111                 result += '*';
112                 return result;
113         }
114 };
115
116
117 /**
118 Loads a statement by calling a function with the statement itself as argument.
119 */
120 template<typename L>
121 class LoaderFunc1<L, const Statement &>: public LoaderAction
122 {
123 private:
124         typedef void (L::*FuncType)(const Statement &);
125
126         FuncType func;
127
128 public:
129         LoaderFunc1(FuncType f): func(f) { }
130
131         virtual void execute(Loader &l, const Statement &st) const
132         {
133                 (dynamic_cast<L &>(l).*func)(st);
134         }
135
136         virtual std::string get_signature() const
137         { return "*"; }
138 };
139
140
141 template<typename L, typename A0, typename A1>
142 class LoaderFunc2: public LoaderAction
143 {
144 private:
145         typedef void (L::*FuncType)(A0, A1);
146
147         FuncType func;
148
149 public:
150         LoaderFunc2(FuncType f): func(f) { }
151
152         virtual void execute(Loader &l, const Statement &st) const
153         {
154                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
155         }
156
157         virtual std::string get_signature() const
158         {
159                 std::string result;
160                 result += TypeInfo<A0>::signature;
161                 result += TypeInfo<A1>::signature;
162                 return result;
163         }
164 };
165
166
167 template<typename L, typename A0, typename A1, typename A2>
168 class LoaderFunc3: public LoaderAction
169 {
170 private:
171         typedef void (L::*FuncType)(A0, A1, A2);
172
173         FuncType func;
174
175 public:
176         LoaderFunc3(FuncType f): func(f) { }
177
178         virtual void execute(Loader &l, const Statement &st) const
179         {
180                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
181         }
182
183         virtual std::string get_signature() const
184         {
185                 std::string result;
186                 result += TypeInfo<A0>::signature;
187                 result += TypeInfo<A1>::signature;
188                 result += TypeInfo<A2>::signature;
189                 return result;
190         }
191 };
192
193
194 template<typename L, typename A0, typename A1, typename A2, typename A3>
195 class LoaderFunc4: public LoaderAction
196 {
197 private:
198         typedef void (L::*FuncType)(A0, A1, A2, A3);
199
200         FuncType func;
201
202 public:
203         LoaderFunc4(FuncType f): func(f) { }
204
205         virtual void execute(Loader &l, const Statement &st) const
206         {
207                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>());
208         }
209
210         virtual std::string get_signature() const
211         {
212                 std::string result;
213                 result += TypeInfo<A0>::signature;
214                 result += TypeInfo<A1>::signature;
215                 result += TypeInfo<A2>::signature;
216                 result += TypeInfo<A3>::signature;
217                 return result;
218         }
219 };
220
221
222 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
223 class LoaderFunc5: public LoaderAction
224 {
225 private:
226         typedef void (L::*FuncType)(A0, A1, A2, A3, A4);
227
228         FuncType func;
229
230 public:
231         LoaderFunc5(FuncType f): func(f) { }
232
233         virtual void execute(Loader &l, const Statement &st) const
234         {
235                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>(), st.args[4].get<A4>());
236         }
237
238         virtual std::string get_signature() const
239         {
240                 std::string result;
241                 result += TypeInfo<A0>::signature;
242                 result += TypeInfo<A1>::signature;
243                 result += TypeInfo<A2>::signature;
244                 result += TypeInfo<A3>::signature;
245                 result += TypeInfo<A4>::signature;
246                 return result;
247         }
248 };
249
250
251 template<typename L, typename T0>
252 class LoadValue1: public LoaderAction
253 {
254 private:
255         typedef T0 L::*Pointer0Type;
256
257         Pointer0Type ptr0;
258
259 public:
260         LoadValue1(Pointer0Type p0): ptr0(p0) { }
261
262         virtual void execute(Loader &l, const Statement &st) const
263         {
264                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = st.args[0].get<T0>();
265         }
266
267         virtual std::string get_signature() const
268         { return std::string(1, TypeInfo<T0>::signature); }
269 };
270
271
272 template<typename L, typename T0>
273 class LoadValue1<L, T0 *>: public LoaderAction
274 {
275 private:
276         typedef T0 *L::*Pointer0Type;
277
278         Pointer0Type ptr0;
279
280 public:
281         LoadValue1(Pointer0Type p0): ptr0(p0) { }
282
283         virtual void execute(Loader &l, const Statement &st) const
284         {
285                 typename L::Loader &ldr = dynamic_cast<typename L::Loader &>(l);
286                 if(!ldr.is_pointer_reload_allowed() && ldr.get_object().*ptr0)
287                         throw InvalidState("The pointer has already been loaded");
288                 ldr.get_object().*ptr0 = ldr.get_collection().template get<T0>(st.args[0].get<std::string>());
289         }
290
291         virtual std::string get_signature() const
292         { return std::string(1, TypeInfo<std::string>::signature); }
293 };
294
295
296 template<typename L, typename T0, typename T1>
297 class LoadValue2: public LoaderAction
298 {
299 private:
300         typedef T0 L::*Pointer0Type;
301         typedef T1 L::*Pointer1Type;
302
303         Pointer0Type ptr0;
304         Pointer1Type ptr1;
305
306 public:
307         LoadValue2(Pointer0Type p0, Pointer1Type p1): ptr0(p0), ptr1(p1) { }
308
309         virtual void execute(Loader &l, const Statement &st) const
310         {
311                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = st.args[0].get<T0>();
312                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr1 = st.args[1].get<T1>();
313         }
314
315         virtual std::string get_signature() const
316         {
317                 std::string result;
318                 result += TypeInfo<T0>::signature;
319                 result += TypeInfo<T1>::signature;
320                 return result;
321         }
322 };
323
324 } // namespace DataFile
325 } // namespace Msp
326
327 #endif