1 #ifndef MSP_DATAFILE_LOADER_H_
2 #define MSP_DATAFILE_LOADER_H_
5 #include <msp/io/file.h>
6 #include "loaderaction.h"
15 Base class for data loaders. This class only provides core functionality.
16 You'll almost certainly want to use one of the BasicLoader classes instead.
18 Under normal circumstances, a class capable of being loaded should have a
19 nested typed called Loader which resolves to a descendant of this class. If
20 another structure is used, the loader object must be constructed manually.
22 A loader class should execute one or more calls to the various add() functions
23 to register actions with expected keywords. Currently possible actions are
24 calling a function of the loader, storing values in member variables of an
25 object and ignoring the statement. If a unexpected keyword is encountered, an
26 exception is thrown and the loading is aborted.
28 A sub-object can be loaded with one of the load_sub functions.
30 When loading has finished successfully, the virtual function finish() is
31 called. Any post-processing of the data should be placed here and not in the
34 See also classes ObjectLoader and CollectionObjectLoader in objectloader.h.
39 typedef std::map<StatementKey, LoaderAction *> ActionMap;
44 const Statement *cur_st;
47 std::vector<Loader *> aux_loaders;
55 /** Loads statements from a parser. */
59 /** Loads data from a statement. */
60 void load(const Statement &st);
62 /** Loads statemsnts from a parser, feeding them directly to actions. */
63 void load_direct(Parser &, unsigned);
65 /** Processes a single statement */
66 void load_statement(const Statement &st);
69 /** Loads a sub-object from the statement being processed. The Loader class
70 of the sub-object is automatically used. */
74 typename S::Loader ldr(s);
78 /** Loads a sub-object from the statement being processed with an extra
79 parameter for the Loader. The Loader class of the sub-object is
80 automatically used. */
81 template<typename S, typename T>
82 void load_sub(S &s, T &p)
84 typename S::Loader ldr(s, p);
88 /** Processes the current statement's substatements with another Loader. */
89 void load_sub_with(Loader &);
91 /** Adds a keyword that is loaded by calling a function. */
93 void add(const std::string &k, void (L::*func)())
94 { add(k, new LoaderFunc0<L>(func)); }
96 template<typename L, typename A0>
97 void add(const std::string &k, void (L::*func)(A0))
98 { add(k, new LoaderFunc1<L, A0>(func)); }
100 #if __cplusplus>=201103L
101 template<typename L, typename... Args>
102 void add(const std::string &k, void (L::*func)(Args...))
103 { add(k, new LoaderFuncN<L, Args...>(func)); }
106 template<typename L, typename A0, typename A1>
107 void add(const std::string &k, void (L::*func)(A0, A1))
108 { add(k, new LoaderFunc2<L, A0, A1>(func)); }
110 template<typename L, typename A0, typename A1, typename A2>
111 void add(const std::string &k, void (L::*func)(A0, A1, A2))
112 { add(k, new LoaderFunc3<L, A0, A1, A2>(func)); }
114 template<typename L, typename A0, typename A1, typename A2, typename A3>
115 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
116 { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
118 template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
119 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
120 { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
123 #if __cplusplus>=201103L
124 /** Adds a keyword that is loaded by calling a function with a bound
126 template<typename L, typename B0, typename... Args>
127 void add(const std::string &k, void (L::*func)(B0, Args...), const typename RemoveReference<B0>::Type &b0)
128 { add(k, new LoaderFuncNBound1<L, B0, Args...>(func, b0)); }
131 /** Adds a keyword that is loaded into a member of the loaded object. */
132 template<typename L, typename T0>
133 void add(const std::string &k, T0 L::*p0)
134 { add(k, new LoadValue1<L, T0>(p0)); }
136 template<typename L, typename T0, typename T1>
137 void add(const std::string &k, T0 L::*p0, T1 L::*p1)
138 { add(k, new LoadValue2<L, T0, T1>(p0, p1)); }
140 /** Adds a keyword that is recognized but ignored. */
141 void add(const std::string &k)
145 void add(const std::string &, LoaderAction *);
148 void add_auxiliary_loader(Loader &);
151 bool has_action(const StatementKey &) const;
152 LoaderAction *find_action(const StatementKey &) const;
155 /** Returns the source of the statement being processed. This can be used
156 to implement relative paths in include-like statements. Note that the
157 source may not necessarily be a file. */
158 const std::string &get_source() const;
160 /** Returns the keyword of the statement being processed. Can be used to
161 implement dynamic keywords. */
162 const std::string &get_keyword() const;
164 virtual void finish() { }
168 #if __cplusplus>=201103L
170 Loads an object from a file. The object must have a public Loader class. Any
171 extra arguments are passed to the Loader constructor.
173 template<typename T, typename... Args>
174 void load(T &obj, const std::string &fn, Args &... args)
176 IO::BufferedFile in(fn);
178 Parser parser(in, fn);
179 typename T::Loader loader(obj, args...);
184 Loads an object from a file stored in a collection. The object must havea
185 public Loader class. The collection is passed to the Loader constructor,
186 followed by any extra arguments.
188 template<typename T, typename... Args>
189 void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &... args)
191 RefPtr<IO::Seekable> in = coll.open_raw(fn);
193 throw IO::file_not_found(fn);
195 Parser parser(*in, fn);
196 typename T::Loader loader(obj, coll, args...);
201 Loads an object from a file stored in a collection. The object must havea
202 public Loader class. Any extra arguments are passed to the Loader constructor.
204 template<typename T, typename C, typename... Args>
205 typename EnableIf<NeedsCollection<typename T::Loader>::value, void>::No load(T &obj, C &coll, const std::string &fn, Args &... args)
207 RefPtr<IO::Seekable> in = coll.open_raw(fn);
209 throw IO::file_not_found(fn);
211 Parser parser(*in, fn);
212 typename T::Loader loader(obj, args...);
219 Loads an object from a file. The object must have a public Loader class.
222 void load(T &obj, const std::string &fn)
224 IO::BufferedFile in(fn);
226 Parser parser(in, fn);
227 typename T::Loader loader(obj);
232 Loads an object from a file, passing one extra argument to the Loader
233 constructor. The object must have a public Loader class.
235 template<typename T, typename U>
236 void load(T &obj, const std::string &fn, U &arg)
238 IO::BufferedFile in(fn);
240 Parser parser(in, fn);
241 typename T::Loader loader(obj, arg);
246 } // namespace DataFile