X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Floader.h;h=574ecce0c11b5bac9af56d82b6a0782a5288d8b6;hp=fe928048508d208aafe339def238a4cdc722dc2d;hb=9c95942d24a92abea14bb9e11d33daae2d017321;hpb=1a3b30ea35fbc19e56bbd35e4ee1811d8d5e02a4 diff --git a/source/loader.h b/source/loader.h index fe92804..574ecce 100644 --- a/source/loader.h +++ b/source/loader.h @@ -4,6 +4,7 @@ #include #include #include "loaderaction.h" +#include "meta.h" #include "parser.h" #include "statement.h" @@ -32,24 +33,30 @@ destructor. See also classes ObjectLoader and CollectionObjectLoader in objectloader.h. */ -class Loader +class Loader: private NonCopyable { -private: - typedef std::map ActionMap; +protected: + class ActionMap: public std::map, private NonCopyable + { + public: + ~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::list aux_loaders; + std::vector aux_loaders; protected: bool check_sub_loads; Loader(); public: - virtual ~Loader(); + virtual ~Loader() { } /** Loads statements from a parser. */ void load(Parser &p); @@ -87,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)()) @@ -96,21 +108,15 @@ protected: void add(const std::string &k, void (L::*func)(A0)) { add(k, new LoaderFunc1(func)); } - template - void add(const std::string &k, void (L::*func)(A0, A1)) - { add(k, new LoaderFunc2(func)); } + template + void add(const std::string &k, void (L::*func)(Args...)) + { add(k, new LoaderFuncN(func)); } - template - void add(const std::string &k, void (L::*func)(A0, A1, A2)) - { add(k, new LoaderFunc3(func)); } - - template - void add(const std::string &k, void (L::*func)(A0, A1, A2, A3)) - { add(k, new LoaderFunc4(func)); } - - template - void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4)) - { add(k, new LoaderFunc5(func)); } + /** 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)); } /** Adds a keyword that is loaded into a member of the loaded object. */ template @@ -150,25 +156,49 @@ protected: /** -Loads an object from a file. The object must have a public Loader class. +Loads an object from a file. The object must have a public Loader class. Any +extra arguments are passed to the Loader constructor. */ -template -void load(T &obj, const std::string &fn) +template +void load(T &obj, const std::string &fn, Args &... args) { IO::BufferedFile in(fn); Parser parser(in, fn); - typename T::Loader loader(obj); + typename T::Loader loader(obj, args...); + loader.load(parser); +} + +/** +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); } -template -void load(T &obj, const std::string &fn, U &arg) +/** +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 +typename EnableIf::value, void>::No load(T &obj, C &coll, const std::string &fn, Args &... args) { - IO::BufferedFile in(fn); + RefPtr in = coll.open_raw(fn); + if(!in) + throw IO::file_not_found(fn); - Parser parser(in, fn); - typename T::Loader loader(obj, arg); + Parser parser(*in, fn); + typename T::Loader loader(obj, args...); loader.load(parser); }