]> git.tdb.fi Git - libs/datafile.git/blob - source/loaderaction.h
Allow overloading keywords with different signatures
[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 &st) const
51         {
52                 if(st.args.size()!=0) throw TypeError("Wrong number of arguments");
53                 (dynamic_cast<L &>(l).*func)();
54         };
55
56         virtual std::string get_signature() const
57         { return std::string(); }
58 };
59
60
61 /**
62 Loads a statement by calling a function that takes one argument.
63 */
64 template<typename L, typename A0>
65 class LoaderFunc1: public LoaderAction
66 {
67 private:
68         typedef void (L::*FuncType)(A0);
69
70         FuncType func;
71
72 public:
73         LoaderFunc1(FuncType f): func(f) { }
74
75         virtual void execute(Loader &l, const Statement &st) const
76         {
77                 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
78                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>());
79         }
80
81         virtual std::string get_signature() const
82         { return std::string(1, TypeInfo<A0>::signature); }
83 };
84
85
86 /**
87 Loads a statement by calling a function that takes an array of values.
88 */
89 template<typename L, typename A0>
90 class LoaderFunc1<L, const std::vector<A0> &>: public LoaderAction
91 {
92 private:
93         typedef void (L::*FuncType)(const std::vector<A0> &);
94
95         FuncType func;
96
97 public:
98         LoaderFunc1(FuncType f): func(f) { }
99
100         virtual void execute(Loader &l, const Statement &st) const
101         {
102                 std::vector<A0> values;
103                 values.reserve(st.args.size());
104                 for(Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
105                         values.push_back(i->get<A0>());
106                 (dynamic_cast<L &>(l).*func)(values);
107         }
108
109         virtual std::string get_signature() const
110         {
111                 std::string result;
112                 result += TypeInfo<A0>::signature;
113                 result += '*';
114                 return result;
115         }
116 };
117
118
119 /**
120 Loads a statement by calling a function with the statement itself as argument.
121 */
122 template<typename L>
123 class LoaderFunc1<L, const Statement &>: public LoaderAction
124 {
125 private:
126         typedef void (L::*FuncType)(const Statement &);
127
128         FuncType func;
129
130 public:
131         LoaderFunc1(FuncType f): func(f) { }
132
133         virtual void execute(Loader &l, const Statement &st) const
134         {
135                 (dynamic_cast<L &>(l).*func)(st);
136         }
137
138         virtual std::string get_signature() const
139         { return "*"; }
140 };
141
142
143 template<typename L, typename A0, typename A1>
144 class LoaderFunc2: public LoaderAction
145 {
146 private:
147         typedef void (L::*FuncType)(A0, A1);
148
149         FuncType func;
150
151 public:
152         LoaderFunc2(FuncType f): func(f) { }
153
154         virtual void execute(Loader &l, const Statement &st) const
155         {
156                 if(st.args.size()!=2) throw TypeError("Wrong number of arguments");
157                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
158         }
159
160         virtual std::string get_signature() const
161         {
162                 std::string result;
163                 result += TypeInfo<A0>::signature;
164                 result += TypeInfo<A1>::signature;
165                 return result;
166         }
167 };
168
169
170 template<typename L, typename A0, typename A1, typename A2>
171 class LoaderFunc3: public LoaderAction
172 {
173 private:
174         typedef void (L::*FuncType)(A0, A1, A2);
175
176         FuncType func;
177
178 public:
179         LoaderFunc3(FuncType f): func(f) { }
180
181         virtual void execute(Loader &l, const Statement &st) const
182         {
183                 if(st.args.size()!=3) throw TypeError("Wrong number of arguments");
184                 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
185         }
186
187         virtual std::string get_signature() const
188         {
189                 std::string result;
190                 result += TypeInfo<A0>::signature;
191                 result += TypeInfo<A1>::signature;
192                 result += TypeInfo<A2>::signature;
193                 return result;
194         }
195 };
196
197
198 template<typename L, typename A0, typename A1, typename A2, typename A3>
199 class LoaderFunc4: public LoaderAction
200 {
201 private:
202         typedef void (L::*FuncType)(A0, A1, A2, A3);
203
204         FuncType func;
205
206 public:
207         LoaderFunc4(FuncType f): func(f) { }
208
209         virtual void execute(Loader &l, const Statement &st) const
210         {
211                 if(st.args.size()!=4) throw TypeError("Wrong number of arguments");
212                 (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>());
213         }
214
215         virtual std::string get_signature() const
216         {
217                 std::string result;
218                 result += TypeInfo<A0>::signature;
219                 result += TypeInfo<A1>::signature;
220                 result += TypeInfo<A2>::signature;
221                 result += TypeInfo<A3>::signature;
222                 return result;
223         }
224 };
225
226
227 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
228 class LoaderFunc5: public LoaderAction
229 {
230 private:
231         typedef void (L::*FuncType)(A0, A1, A2, A3, A4);
232
233         FuncType func;
234
235 public:
236         LoaderFunc5(FuncType f): func(f) { }
237
238         virtual void execute(Loader &l, const Statement &st) const
239         {
240                 if(st.args.size()!=5) throw TypeError("Wrong number of arguments");
241                 (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>());
242         }
243
244         virtual std::string get_signature() const
245         {
246                 std::string result;
247                 result += TypeInfo<A0>::signature;
248                 result += TypeInfo<A1>::signature;
249                 result += TypeInfo<A2>::signature;
250                 result += TypeInfo<A3>::signature;
251                 result += TypeInfo<A4>::signature;
252                 return result;
253         }
254 };
255
256
257 template<typename L, typename T0>
258 class LoadValue1: public LoaderAction
259 {
260 private:
261         typedef T0 L::*Pointer0Type;
262
263         Pointer0Type ptr0;
264
265 public:
266         LoadValue1(Pointer0Type p0): ptr0(p0) { }
267
268         virtual void execute(Loader &l, const Statement &st) const
269         {
270                 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
271                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0=st.args[0].get<T0>();
272         }
273
274         virtual std::string get_signature() const
275         { return std::string(1, TypeInfo<T0>::signature); }
276 };
277
278
279 template<typename L, typename T0>
280 class LoadValue1<L, T0 *>: public LoaderAction
281 {
282 private:
283         typedef T0 *L::*Pointer0Type;
284
285         Pointer0Type ptr0;
286
287 public:
288         LoadValue1(Pointer0Type p0): ptr0(p0) { }
289
290         virtual void execute(Loader &l, const Statement &st) const
291         {
292                 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
293                 typename L::Loader &ldr=dynamic_cast<typename L::Loader &>(l);
294                 ldr.get_object().*ptr0=ldr.get_collection().template get<T0>(st.args[0].get<std::string>());
295         }
296
297         virtual std::string get_signature() const
298         { return std::string(1, TypeInfo<std::string>::signature); }
299 };
300
301
302 template<typename L, typename T0, typename T1>
303 class LoadValue2: public LoaderAction
304 {
305 private:
306         typedef T0 L::*Pointer0Type;
307         typedef T1 L::*Pointer1Type;
308
309         Pointer0Type ptr0;
310         Pointer1Type ptr1;
311
312 public:
313         LoadValue2(Pointer0Type p0, Pointer1Type p1): ptr0(p0), ptr1(p1) { }
314
315         virtual void execute(Loader &l, const Statement &st) const
316         {
317                 if(st.args.size()!=2) throw TypeError("Wrong number of arguments");
318                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0=st.args[0].get<T0>();
319                 dynamic_cast<typename L::Loader &>(l).get_object().*ptr1=st.args[1].get<T1>();
320         }
321
322         virtual std::string get_signature() const
323         {
324                 std::string result;
325                 result += TypeInfo<T0>::signature;
326                 result += TypeInfo<T1>::signature;
327                 return result;
328         }
329 };
330
331 } // namespace DataFile
332 } // namespace Msp
333
334 #endif