X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Floader.h;h=cf2b5454b907a038e66745a7ecd7fadf239dcf56;hb=14f031aead619ce8a3fff1c283c3d205d421cd1f;hp=3c4785c493017eadeef3f2c20bb70e05b4bb9cf8;hpb=7df5e45c7f414f6a07681dc4ec2abb63b091a309;p=libs%2Fdatafile.git diff --git a/source/loader.h b/source/loader.h index 3c4785c..cf2b545 100644 --- a/source/loader.h +++ b/source/loader.h @@ -3,8 +3,8 @@ #include #include -#include "except.h" #include "loaderaction.h" +#include "meta.h" #include "parser.h" #include "statement.h" @@ -31,35 +31,32 @@ When loading has finished successfully, the virtual function finish() is called. Any post-processing of the data should be placed here and not in the destructor. -See also classes BasicLoader and BasicLoader2. +See also classes ObjectLoader and CollectionObjectLoader in objectloader.h. */ -class Loader +class Loader: private NonCopyable { -private: - struct ActionKey +protected: + class ActionMap: public std::map, private NonCopyable { - std::string keyword; - std::string signature; - - ActionKey(const std::string &, const std::string &); - - bool operator<(const ActionKey &) const; + public: + ~ActionMap(); }; - typedef std::map ActionMap; - - ActionMap actions; +private: + ActionMap local_actions; + ActionMap *actions; + Parser *cur_parser; + unsigned cur_level; const Statement *cur_st; bool sub_loaded; + bool direct; + std::vector aux_loaders; protected: - bool allow_pointer_reload; bool check_sub_loads; Loader(); public: - virtual ~Loader(); - - bool is_pointer_reload_allowed() const { return allow_pointer_reload; } + virtual ~Loader() { } /** Loads statements from a parser. */ void load(Parser &p); @@ -68,6 +65,9 @@ private: /** Loads data from a statement. */ void load(const Statement &st); + /** Loads statemsnts from a parser, feeding them directly to actions. */ + void load_direct(Parser &, unsigned); + /** Processes a single statement */ void load_statement(const Statement &st); @@ -94,6 +94,11 @@ protected: /** Processes the current statement's substatements with another Loader. */ void load_sub_with(Loader &); + /** Sets the actions to be used when loading. If the map is empty, + init_actions will be called. */ + void set_actions(ActionMap &); + virtual void init_actions() { } + /** Adds a keyword that is loaded by calling a function. */ template void add(const std::string &k, void (L::*func)()) @@ -103,6 +108,12 @@ protected: void add(const std::string &k, void (L::*func)(A0)) { add(k, new LoaderFunc1(func)); } +#if __cplusplus>=201103L + template + void add(const std::string &k, void (L::*func)(Args...)) + { add(k, new LoaderFuncN(func)); } + +#else template void add(const std::string &k, void (L::*func)(A0, A1)) { add(k, new LoaderFunc2(func)); } @@ -118,6 +129,15 @@ protected: template void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4)) { add(k, new LoaderFunc5(func)); } +#endif + +#if __cplusplus>=201103L + /** Adds a keyword that is loaded by calling a function with a bound + first argument. */ + template + void add(const std::string &k, void (L::*func)(B0, Args...), const typename RemoveReference::Type &b0) + { add(k, new LoaderFuncNBound1(func, b0)); } +#endif /** Adds a keyword that is loaded into a member of the loaded object. */ template @@ -135,58 +155,76 @@ protected: private: void add(const std::string &, LoaderAction *); - LoaderAction *find_action(const ActionKey &) const; +protected: + void add_auxiliary_loader(Loader &); + +private: + bool has_action(const StatementKey &) const; + LoaderAction *find_action(const StatementKey &) const; protected: /** Returns the source of the statement being processed. This can be used to implement relative paths in include-like statements. Note that the source may not necessarily be a file. */ - const std::string &get_source() const - { - if(!cur_st) - throw InvalidState("get_source called without current statement"); - return cur_st->source; - } + const std::string &get_source() const; + + /** Returns the keyword of the statement being processed. Can be used to + implement dynamic keywords. */ + const std::string &get_keyword() const; virtual void finish() { } }; +#if __cplusplus>=201103L /** -Deprecated. See ObjectLoader in objectloader.h. +Loads an object from a file. The object must have a public Loader class. Any +extra arguments are passed to the Loader constructor. */ -template -class BasicLoader: public Loader +template +void load(T &obj, const std::string &fn, Args &... args) { -public: - typedef O Object; + IO::BufferedFile in(fn); -protected: - O &obj; + Parser parser(in, fn); + typename T::Loader loader(obj, args...); + loader.load(parser); +} -public: - BasicLoader(O &o): obj(o) { } - O &get_object() const { return obj; } -}; +/** +Loads an object from a file stored in a collection. The object must have a +public Loader class. The collection is passed to the Loader constructor, +followed by any extra arguments. +*/ +template +void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &... args) +{ + RefPtr in = coll.open_raw(fn); + if(!in) + throw IO::file_not_found(fn); + Parser parser(*in, fn); + typename T::Loader loader(obj, coll, args...); + loader.load(parser); +} /** -Deprecated. See CollectionObjectLoader in objectloader.h. +Loads an object from a file stored in a collection. The object must havea +public Loader class. Any extra arguments are passed to the Loader constructor. */ -template -class BasicLoader2: public BasicLoader +template +typename EnableIf::value, void>::No load(T &obj, C &coll, const std::string &fn, Args &... args) { -public: - typedef C Collection; - -protected: - C &coll; + RefPtr in = coll.open_raw(fn); + if(!in) + throw IO::file_not_found(fn); -public: - BasicLoader2(O &o, C &c): BasicLoader(o), coll(c) { } - C &get_collection() const { return coll; } -}; + Parser parser(*in, fn); + typename T::Loader loader(obj, args...); + loader.load(parser); +} +#else /** Loads an object from a file. The object must have a public Loader class. @@ -201,6 +239,10 @@ void load(T &obj, const std::string &fn) loader.load(parser); } +/** +Loads an object from a file, passing one extra argument to the Loader +constructor. The object must have a public Loader class. +*/ template void load(T &obj, const std::string &fn, U &arg) { @@ -210,6 +252,7 @@ void load(T &obj, const std::string &fn, U &arg) typename T::Loader loader(obj, arg); loader.load(parser); } +#endif } // namespace DataFile } // namespace Msp