]> git.tdb.fi Git - libs/datafile.git/commitdiff
Change Collection interface to use pointers consistently
authorMikko Rasa <tdb@tdb.fi>
Fri, 2 Nov 2007 19:43:21 +0000 (19:43 +0000)
committerMikko Rasa <tdb@tdb.fi>
Fri, 2 Nov 2007 19:43:21 +0000 (19:43 +0000)
Make it possible for creators to return 0 pointers successfully
Add LoaderFunc5

source/collection.h
source/loader.h

index 6ddbe6ed65c980d035b30160ad1eca18c0390f1f..24be69dd2f70cd07d425453b3121788b2ff60086 100644 (file)
@@ -105,19 +105,22 @@ private:
                virtual ~ItemCreatorBase() { }
 
                template<typename S>
-               S *create(Collection &coll, const std::string &name)
+               bool create(Collection &coll, const std::string &name, S *&ptr)
                {
                        ItemCreatorBridge<S> *creator=dynamic_cast<ItemCreatorBridge<S> *>(this);
                        if(creator)
-                               return creator->create(coll, name);
-                       return 0;
+                       {
+                               creator->create(coll, name, ptr);
+                               return true;
+                       }
+                       return false;
                }
        };
 
        template<typename S>
        struct ItemCreatorBridge: public ItemCreatorBase
        {
-               virtual S *create(Collection &, const std::string &) const =0;
+               virtual bool create(Collection &, const std::string &, S *&) const =0;
        };
 
        template<typename T, typename S, typename C>
@@ -198,7 +201,7 @@ public:
        Gets an object of a specific type from the collection.
        */
        template<typename T>
-       T &get(const std::string &name) const
+       T *get(const std::string &name) const
        {
                typedef typename RemoveConst<T>::Type NCT;
 
@@ -219,7 +222,7 @@ public:
        invoked.
        */
        template<typename T>
-       T &get(const std::string &name)
+       T *get(const std::string &name)
        {
                typedef typename RemoveConst<T>::Type NCT;
 
@@ -227,12 +230,15 @@ public:
                if(i==items.end())
                {
                        for(ItemCreatorSeq::iterator j=creators.begin(); j!=creators.end(); ++j)
-                               if(NCT *d=(*j)->create<NCT>(*this, name))
+                       {
+                               NCT *d=0;
+                               if((*j)->create(*this, name, d))
                                {
                                        // We already know that the item didn't exist yet
                                        items[name]=new Item<NCT>(d);
                                        return *d;
                                }
+                       }
                        throw KeyError("Item '"+name+"' not found in collection");
                }
 
index 8d26a418a0f5d9cdec52a6ecc85160ff4ee1c4e4..acc84fe024dd080d702bb4d4b3af52ce4ff19e12 100644 (file)
@@ -151,6 +151,23 @@ private:
 };
 
 
+template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
+class LoaderFunc5: public LoaderAction
+{
+public:
+       typedef void (L::*FuncType)(A0, A1, A2, A3, A4);
+
+       LoaderFunc5(FuncType f): func(f) { }
+       void execute(Loader &l, const Statement &st) const
+       {
+               if(st.args.size()!=5) throw TypeError(st.get_location()+": Wrong number of arguments");
+               (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>(), st.args[4].get<A4>());
+       }
+private:
+       FuncType func;
+};
+
+
 template<typename L, typename T0>
 class LoadValue1: public LoaderAction
 {
@@ -257,6 +274,10 @@ protected:
        void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
        { add(k, new LoaderFunc4<L, A0, A1, A2, A3>(func)); }
 
+       template<typename L, typename A0, typename A1, typename A2, typename A3, typename A4>
+       void add(const std::string &k, void (L::*func)(A0, A1, A2, A3, A4))
+       { add(k, new LoaderFunc5<L, A0, A1, A2, A3, A4>(func)); }
+
        /**
        Adds a keyword that is loaded into a variable of the loaded object.
        */