1 #ifndef MSP_DATAFILE_LOADERACTION_H_
2 #define MSP_DATAFILE_LOADERACTION_H_
4 #include <msp/core/meta.h>
5 #include "argumentstore.h"
11 #if __cplusplus>=201103L
13 std::string create_signature(const std::string &prefix = std::string())
14 { return prefix+std::string(1, TypeInfo<T>::signature); }
16 template<typename T0, typename T1, typename... Tail>
17 std::string create_signature(const std::string &prefix = std::string())
18 { return create_signature<T1, Tail...>(prefix+std::string(1, TypeInfo<T0>::signature)); }
24 Base class for loader actions.
31 virtual ~LoaderAction() { }
33 /** Called to process a statement. */
34 virtual void execute(Loader &, const Statement &) const = 0;
36 virtual void execute(Loader &, const ArgumentStore &) const = 0;
38 virtual std::string get_signature() const = 0;
43 Loads a statement by calling a function that takes no arguments.
46 class LoaderFunc0: public LoaderAction
49 typedef void (L::*FuncType)();
54 LoaderFunc0(FuncType f): func(f) { }
56 virtual void execute(Loader &l, const Statement &) const
58 (dynamic_cast<L &>(l).*func)();
61 virtual void execute(Loader &l, const ArgumentStore &) const
63 (dynamic_cast<L &>(l).*func)();
66 virtual std::string get_signature() const
67 { return std::string(); }
72 Loads a statement by calling a function that takes one argument.
74 template<typename L, typename A0>
75 class LoaderFunc1: public LoaderAction
78 typedef void (L::*FuncType)(A0);
83 LoaderFunc1(FuncType f): func(f) { }
85 virtual void execute(Loader &l, const Statement &st) const
87 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>());
90 virtual void execute(Loader &l, const ArgumentStore &as) const
92 (dynamic_cast<L &>(l).*func)(as.get<A0>(0));
95 virtual std::string get_signature() const
96 { return std::string(1, TypeInfo<A0>::signature); }
101 Loads a statement by calling a function that takes an array of values.
103 template<typename L, typename A0>
104 class LoaderFunc1<L, const std::vector<A0> &>: public LoaderAction
107 typedef void (L::*FuncType)(const std::vector<A0> &);
112 LoaderFunc1(FuncType f): func(f) { }
114 virtual void execute(Loader &l, const Statement &st) const
116 std::vector<A0> values;
117 values.reserve(st.args.size());
118 for(Statement::Arguments::const_iterator i=st.args.begin(); i!=st.args.end(); ++i)
119 values.push_back(i->get<A0>());
120 (dynamic_cast<L &>(l).*func)(values);
123 virtual void execute(Loader &l, const ArgumentStore &as) const
125 std::vector<A0> values;
126 unsigned n_args = as.get_info().key.signature.size();
127 values.reserve(n_args);
128 for(unsigned i=0; i<n_args; ++i)
129 values.push_back(as.get<A0>(i));
130 (dynamic_cast<L &>(l).*func)(values);
133 virtual std::string get_signature() const
136 result += TypeInfo<A0>::signature;
144 Loads a statement by calling a function with the statement itself as argument.
147 class LoaderFunc1<L, const Statement &>: public LoaderAction
150 typedef void (L::*FuncType)(const Statement &);
155 LoaderFunc1(FuncType f): func(f) { }
157 virtual void execute(Loader &l, const Statement &st) const
159 (dynamic_cast<L &>(l).*func)(st);
162 virtual void execute(Loader &, const ArgumentStore &) const
164 throw std::logic_error("incompatible format");
167 virtual std::string get_signature() const
172 template<typename L, typename A0, typename A1>
173 class LoaderFunc2: public LoaderAction
176 typedef void (L::*FuncType)(A0, A1);
181 LoaderFunc2(FuncType f): func(f) { }
183 virtual void execute(Loader &l, const Statement &st) const
185 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
188 virtual void execute(Loader &l, const ArgumentStore &as) const
190 (dynamic_cast<L &>(l).*func)(as.get<A0>(0), as.get<A1>(1));
193 virtual std::string get_signature() const
196 result += TypeInfo<A0>::signature;
197 result += TypeInfo<A1>::signature;
203 template<typename L, typename A0, typename A1, typename A2>
204 class LoaderFunc3: public LoaderAction
207 typedef void (L::*FuncType)(A0, A1, A2);
212 LoaderFunc3(FuncType f): func(f) { }
214 virtual void execute(Loader &l, const Statement &st) const
216 (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
219 virtual void execute(Loader &l, const ArgumentStore &as) const
221 (dynamic_cast<L &>(l).*func)(as.get<A0>(0), as.get<A1>(1), as.get<A2>(2));
224 virtual std::string get_signature() const
227 result += TypeInfo<A0>::signature;
228 result += TypeInfo<A1>::signature;
229 result += TypeInfo<A2>::signature;
235 template<typename L, typename A0, typename A1, typename A2, typename A3>
236 class LoaderFunc4: public LoaderAction
239 typedef void (L::*FuncType)(A0, A1, A2, A3);
244 LoaderFunc4(FuncType f): func(f) { }
246 virtual void execute(Loader &l, const Statement &st) const
248 (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>());
251 virtual void execute(Loader &l, const ArgumentStore &as) const
253 (dynamic_cast<L &>(l).*func)(as.get<A0>(0), as.get<A1>(1), as.get<A2>(2), as.get<A3>(3));
256 virtual std::string get_signature() const
259 result += TypeInfo<A0>::signature;
260 result += TypeInfo<A1>::signature;
261 result += TypeInfo<A2>::signature;
262 result += TypeInfo<A3>::signature;
268 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
269 class LoaderFunc5: public LoaderAction
272 typedef void (L::*FuncType)(A0, A1, A2, A3, A4);
277 LoaderFunc5(FuncType f): func(f) { }
279 virtual void execute(Loader &l, const Statement &st) const
281 (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>());
284 virtual void execute(Loader &l, const ArgumentStore &as) const
286 (dynamic_cast<L &>(l).*func)(as.get<A0>(0), as.get<A1>(1), as.get<A2>(2), as.get<A3>(3), as.get<A4>(4));
289 virtual std::string get_signature() const
292 result += TypeInfo<A0>::signature;
293 result += TypeInfo<A1>::signature;
294 result += TypeInfo<A2>::signature;
295 result += TypeInfo<A3>::signature;
296 result += TypeInfo<A4>::signature;
302 #if __cplusplus>=201103L
303 template<unsigned I, typename... Args>
309 template<typename L, typename F, typename... Args>
310 static void apply(L &l, F func, const Statement &, Args... args)
315 template<typename L, typename F, typename... Args>
316 static void apply(L &l, F func, const ArgumentStore &, Args... args)
322 template<unsigned I, typename Head, typename... Tail>
323 struct Apply<I, Head, Tail...>
325 template<typename L, typename F, typename... Args>
326 static void apply(L &l, F func, const Statement &st, Args... args)
328 Apply<I+1, Tail...>::apply(l, func, st, args..., st.args[I].get<Head>());
331 template<typename L, typename F, typename... Args>
332 static void apply(L &l, F func, const ArgumentStore &as, Args... args)
334 Apply<I+1, Tail...>::apply(l, func, as, args..., as.get<Head>(I));
339 template<typename L, typename... Args>
340 class LoaderFuncN: public LoaderAction
343 typedef void (L::*FuncType)(Args...);
348 LoaderFuncN(FuncType f): func(f) { }
350 virtual void execute(Loader &l, const Statement &st) const
352 Apply<0, Args...>::apply(dynamic_cast<L &>(l), func, st);
355 virtual void execute(Loader &l, const ArgumentStore &as) const
357 Apply<0, Args...>::apply(dynamic_cast<L &>(l), func, as);
360 virtual std::string get_signature() const
361 { return create_signature<Args...>(); }
365 template<typename L, typename B0, typename... Args>
366 class LoaderFuncNBound1: public LoaderAction
369 typedef void (L::*FuncType)(B0, Args...);
370 typedef typename RemoveReference<B0>::Type Bound0Type;
376 LoaderFuncNBound1(FuncType f, const Bound0Type &b0): func(f), bound0(b0) { }
378 virtual void execute(Loader &l, const Statement &st) const
380 Apply<0, Args...>::apply(dynamic_cast<L &>(l), func, st, bound0);
383 virtual void execute(Loader &l, const ArgumentStore &as) const
385 Apply<0, Args...>::apply(dynamic_cast<L &>(l), func, as, bound0);
388 virtual std::string get_signature() const
389 { return create_signature<Args...>(); }
394 template<typename L, typename T0>
395 class LoadValue1: public LoaderAction
398 typedef T0 L::*Pointer0Type;
403 LoadValue1(Pointer0Type p0): ptr0(p0) { }
405 virtual void execute(Loader &l, const Statement &st) const
407 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = st.args[0].get<T0>();
410 virtual void execute(Loader &l, const ArgumentStore &as) const
412 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = as.get<T0>(0);
415 virtual std::string get_signature() const
416 { return std::string(1, TypeInfo<T0>::signature); }
420 template<typename L, typename T0>
421 class LoadValue1<L, T0 *>: public LoaderAction
424 typedef T0 *L::*Pointer0Type;
429 LoadValue1(Pointer0Type p0): ptr0(p0) { }
431 virtual void execute(Loader &l, const Statement &st) const
433 typename L::Loader &ldr = dynamic_cast<typename L::Loader &>(l);
434 ldr.get_object().*ptr0 = &ldr.get_collection().template get<T0>(st.args[0].get<std::string>());
437 virtual void execute(Loader &l, const ArgumentStore &as) const
439 typename L::Loader &ldr = dynamic_cast<typename L::Loader &>(l);
440 ldr.get_object().*ptr0 = &ldr.get_collection().template get<T0>(as.get<std::string>(0));
443 virtual std::string get_signature() const
444 { return std::string(1, TypeInfo<std::string>::signature); }
448 template<typename L, typename T0, typename T1>
449 class LoadValue2: public LoaderAction
452 typedef T0 L::*Pointer0Type;
453 typedef T1 L::*Pointer1Type;
459 LoadValue2(Pointer0Type p0, Pointer1Type p1): ptr0(p0), ptr1(p1) { }
461 virtual void execute(Loader &l, const Statement &st) const
463 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = st.args[0].get<T0>();
464 dynamic_cast<typename L::Loader &>(l).get_object().*ptr1 = st.args[1].get<T1>();
467 virtual void execute(Loader &l, const ArgumentStore &as) const
469 dynamic_cast<typename L::Loader &>(l).get_object().*ptr0 = as.get<T0>(0);
470 dynamic_cast<typename L::Loader &>(l).get_object().*ptr1 = as.get<T1>(1);
473 virtual std::string get_signature() const
476 result += TypeInfo<T0>::signature;
477 result += TypeInfo<T1>::signature;
482 } // namespace DataFile