From: Mikko Rasa Date: Fri, 25 Aug 2006 16:02:22 +0000 (+0000) Subject: Loader design change X-Git-Tag: 1.0~37 X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=26ab6b6a9e1c1eae7190135d762df8b37c3c60f9;p=libs%2Fdatafile.git Loader design change - SubLoaders have been replaced with load_sub - Loader inheritance should be possible --- diff --git a/source/loader.h b/source/loader.h index 46c878b..2fe0292 100644 --- a/source/loader.h +++ b/source/loader.h @@ -15,157 +15,117 @@ Distributed under the LGPL namespace Msp { namespace Parser { +class Loader; class Statement; -template class LoaderAction { public: - virtual void execute(L &, const Statement &) const=0; + virtual void execute(Loader &, const Statement &) const=0; virtual ~LoaderAction() { } protected: LoaderAction() { } }; template -class LoaderFunc0: public LoaderAction +class LoaderFunc0: public LoaderAction { public: typedef void (L::*FuncType)(); LoaderFunc0(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=0) throw TypeError("Wrong number of arguments"); - (l.*func)(); + (dynamic_cast(l).*func)(); }; private: FuncType func; }; template -class LoaderFunc1: public LoaderAction +class LoaderFunc1: public LoaderAction { public: typedef void (L::*FuncType)(A0); LoaderFunc1(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=1) throw TypeError("Wrong number of arguments"); - (l.*func)(st.args[0].get()); + (dynamic_cast(l).*func)(st.args[0].get()); } private: FuncType func; }; template -class LoaderFunc2: public LoaderAction +class LoaderFunc2: public LoaderAction { public: typedef void (L::*FuncType)(A0, A1); LoaderFunc2(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=2) throw TypeError("Wrong number of arguments"); - (l.*func)(st.args[0].get(), st.args[1].get()); + (dynamic_cast(l).*func)(st.args[0].get(), st.args[1].get()); } private: FuncType func; }; template -class LoaderFunc3: public LoaderAction +class LoaderFunc3: public LoaderAction { public: typedef void (L::*FuncType)(A0, A1, A2); LoaderFunc3(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=3) throw TypeError("Wrong number of arguments"); - (l.*func)(st.args[0].get(), st.args[1].get(), st.args[2].get()); + (dynamic_cast(l).*func)(st.args[0].get(), st.args[1].get(), st.args[2].get()); } private: FuncType func; }; template -class LoaderFunc4: public LoaderAction +class LoaderFunc4: public LoaderAction { public: typedef void (L::*FuncType)(A0, A1, A2, A3); LoaderFunc4(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=4) throw TypeError("Wrong number of arguments"); - (l.*func)(st.args[0].get(), st.args[1].get(), st.args[2].get(), st.args[3].get()); + (dynamic_cast(l).*func)(st.args[0].get(), st.args[1].get(), st.args[2].get(), st.args[3].get()); } private: FuncType func; }; template -class LoadValue: public LoaderAction +class LoadValue: public LoaderAction { public: - typedef T L::ObjectType::*PointerType; + typedef T L::*PointerType; LoadValue(PointerType p): ptr(p) { } - void execute(L &l, const Statement &st) const + void execute(Loader &l, const Statement &st) const { if(st.args.size()!=1) throw TypeError("Wrong number of arguments"); - l.get_object().*ptr=st.args[0].get(); + dynamic_cast(l).get_object().*ptr=st.args[0].get(); } private: PointerType ptr; }; -template -class SubLoader0: public LoaderAction -{ -public: - typedef typename S::ObjectType &(L::*FuncType)(); - - SubLoader0(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const - { - if(st.args.size()!=0) throw TypeError("Wrong number of arguments"); - typename S::ObjectType &obj=(l.*func)(); - S sl(obj); - sl.load(st); - } -private: - FuncType func; -}; - -template -class SubLoader1: public LoaderAction -{ -public: - typedef typename S::ObjectType &(L::*FuncType)(A0); - - SubLoader1(FuncType f): func(f) { } - void execute(L &l, const Statement &st) const - { - if(st.args.size()!=1) throw TypeError("Wrong number of arguments"); - typename S::ObjectType &obj=(l.*func)(st.args[0].get()); - S sl(obj); - sl.load(st); - } -private: - FuncType func; -}; - -template class Loader { public: - typedef C ObjectType; - - C &get_object() { return obj; } void load(const Statement &st) { for(std::list::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i) @@ -182,55 +142,62 @@ public: } virtual ~Loader() { - for(typename ActionMap::iterator i=actions.begin(); i!=actions.end(); ++i) + for(ActionMap::iterator i=actions.begin(); i!=actions.end(); ++i) delete i->second; } protected: - typedef std::map *> ActionMap; - - C &obj; - - Loader(C &o): obj(o) { } + Loader(): cur_st(0) { } + template void add(const std::string &k, void (L::*func)()) { actions.insert(typename ActionMap::value_type(k, new LoaderFunc0(func))); } - template + template void add(const std::string &k, void (L::*func)(A0)) { actions.insert(typename ActionMap::value_type(k, new LoaderFunc1(func))); } - template + template void add(const std::string &k, void (L::*func)(A0, A1)) { actions.insert(typename ActionMap::value_type(k, new LoaderFunc2(func))); } - template + template void add(const std::string &k, void (L::*func)(A0, A1, A2)) { actions.insert(typename ActionMap::value_type(k, new LoaderFunc3(func))); } - template + template void add(const std::string &k, void (L::*func)(A0, A1, A2, A3)) { actions.insert(typename ActionMap::value_type(k, new LoaderFunc4(func))); } - template - void add(const std::string &k, typename S::ObjectType &(L::*func)()) - { actions.insert(typename ActionMap::value_type(k, new SubLoader0(func))); } + template + void add(const std::string &k, T L::*p) + { actions.insert(typename ActionMap::value_type(k, new LoadValue(p))); } - template - void add(const std::string &k, typename S::ObjectType &(L::*func)(A0)) - { actions.insert(typename ActionMap::value_type(k, new SubLoader1(func))); } + template + void load_sub(S &s) + { load_sub(s); } - template - void add(const std::string &k, T C::*p) - { actions.insert(typename ActionMap::value_type(k, new LoadValue(p))); } + template + void load_sub(S &s) + { + if(!cur_st) + throw Exception("load_sub called without current statement"); + L loader(s); + loader.load(*cur_st); + } private: - ActionMap actions; + typedef std::map ActionMap; + + ActionMap actions; + const Statement *cur_st; void load_statement(const Statement &st) { - typename ActionMap::iterator j=actions.find(st.keyword); + cur_st=&st; + ActionMap::iterator j=actions.find(st.keyword); if(j==actions.end()) throw Exception(st.get_location()+": Unknown keyword '"+st.keyword+"'"); - j->second->execute(dynamic_cast(*this), st); + j->second->execute(*this, st); + cur_st=0; } };