]> git.tdb.fi Git - libs/datafile.git/commitdiff
Loader design change
authorMikko Rasa <tdb@tdb.fi>
Fri, 25 Aug 2006 16:02:22 +0000 (16:02 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 25 Aug 2006 16:02:22 +0000 (16:02 +0000)
- SubLoaders have been replaced with load_sub
- Loader inheritance should be possible

source/loader.h

index 46c878b09ef6a65c63fad2a266d28befa358f2ef..2fe0292bff01d5a6cdbab98e387daf0bbfab309e 100644 (file)
@@ -15,157 +15,117 @@ Distributed under the LGPL
 namespace Msp {
 namespace Parser {
 
+class Loader;
 class Statement;
 
-template<typename L>
 class LoaderAction
 {
 public:
-       virtual void execute(L &, const Statement &) const=0;
+       virtual void execute(Loader &, const Statement &) const=0;
        virtual ~LoaderAction() { }
 protected:
        LoaderAction() { }
 };
 
 template<typename L>
-class LoaderFunc0: public LoaderAction<L>
+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 &>(l).*func)();
        };
 private:
        FuncType func;
 };
 
 template<typename L, typename A0>
-class LoaderFunc1: public LoaderAction<L>
+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<A0>());
+               (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>());
        }
 private:
        FuncType func;
 };
 
 template<typename L, typename A0, typename A1>
-class LoaderFunc2: public LoaderAction<L>
+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<A0>(), st.args[1].get<A1>());
+               (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
        }
 private:
        FuncType func;
 };
 
 template<typename L, typename A0, typename A1, typename A2>
-class LoaderFunc3: public LoaderAction<L>
+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<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
+               (dynamic_cast<L &>(l).*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
        }
 private:
        FuncType func;
 };
 
 template<typename L, typename A0, typename A1, typename A2, typename A3>
-class LoaderFunc4: public LoaderAction<L>
+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<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>());
+               (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>());
        }
 private:
        FuncType func;
 };
 
 template<typename L, typename T>
-class LoadValue: public LoaderAction<L>
+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<T>();
+               dynamic_cast<typename L::Loader &>(l).get_object().*ptr=st.args[0].get<T>();
        }
 private:
        PointerType ptr;
 };
 
-template<typename L, typename S>
-class SubLoader0: public LoaderAction<L>
-{
-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<typename L, typename S, typename A0>
-class SubLoader1: public LoaderAction<L>
-{
-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<A0>());
-               S sl(obj);
-               sl.load(st);
-       }
-private:
-       FuncType func;
-};
-
-template<typename C, typename L>
 class Loader
 {
 public:
-       typedef C ObjectType;
-       
-       C &get_object() { return obj; }
        void load(const Statement &st)
        {
                for(std::list<Statement>::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<std::string, LoaderAction<L > *> ActionMap;
-
-       C &obj;
-       
-       Loader(C &o): obj(o) { }
+       Loader(): cur_st(0) { }
        
+       template<typename L>
        void add(const std::string &k, void (L::*func)())
        { actions.insert(typename ActionMap::value_type(k, new LoaderFunc0<L>(func))); }
        
-       template<typename A0>
+       template<typename L, typename A0>
        void add(const std::string &k, void (L::*func)(A0))
        { actions.insert(typename ActionMap::value_type(k, new LoaderFunc1<L, A0>(func))); }
        
-       template<typename A0, typename A1>
+       template<typename L, typename A0, typename A1>
        void add(const std::string &k, void (L::*func)(A0, A1))
        { actions.insert(typename ActionMap::value_type(k, new LoaderFunc2<L, A0, A1>(func))); }
        
-       template<typename A0, typename A1, typename A2>
+       template<typename L, typename A0, typename A1, typename A2>
        void add(const std::string &k, void (L::*func)(A0, A1, A2))
        { actions.insert(typename ActionMap::value_type(k, new LoaderFunc3<L, A0, A1, A2>(func))); }
        
-       template<typename A0, typename A1, typename A2, typename A3>
+       template<typename L, typename A0, typename A1, typename A2, typename A3>
        void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
        { actions.insert(typename ActionMap::value_type(k, new LoaderFunc4<L, A0, A1, A2, A3>(func))); }
 
-       template<typename S>
-       void add(const std::string &k, typename S::ObjectType &(L::*func)())
-       { actions.insert(typename ActionMap::value_type(k, new SubLoader0<L, S>(func))); }
+       template<typename L, typename T>
+       void add(const std::string &k, T L::*p)
+       { actions.insert(typename ActionMap::value_type(k, new LoadValue<L, T>(p))); }
 
-       template<typename S, typename A0>
-       void add(const std::string &k, typename S::ObjectType &(L::*func)(A0))
-       { actions.insert(typename ActionMap::value_type(k, new SubLoader1<L, S, A0>(func))); }
+       template<typename S>
+       void load_sub(S &s)
+       { load_sub<S, typename S::Loader>(s); }
 
-       template<typename T>
-       void add(const std::string &k, T C::*p)
-       { actions.insert(typename ActionMap::value_type(k, new LoadValue<L, T>(p))); }
+       template<typename S, typename L>
+       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<std::string, LoaderAction *> 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<L &>(*this), st);
+               j->second->execute(*this, st);
+               cur_st=0;
        }
 };