From 6678cf025ca97dd398a9304b0578f146d1f7af80 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 2 Nov 2007 19:43:21 +0000 Subject: [PATCH] Change Collection interface to use pointers consistently Make it possible for creators to return 0 pointers successfully Add LoaderFunc5 --- source/collection.h | 20 +++++++++++++------- source/loader.h | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/source/collection.h b/source/collection.h index 6ddbe6e..24be69d 100644 --- a/source/collection.h +++ b/source/collection.h @@ -105,19 +105,22 @@ private: virtual ~ItemCreatorBase() { } template - S *create(Collection &coll, const std::string &name) + bool create(Collection &coll, const std::string &name, S *&ptr) { ItemCreatorBridge *creator=dynamic_cast *>(this); if(creator) - return creator->create(coll, name); - return 0; + { + creator->create(coll, name, ptr); + return true; + } + return false; } }; template struct ItemCreatorBridge: public ItemCreatorBase { - virtual S *create(Collection &, const std::string &) const =0; + virtual bool create(Collection &, const std::string &, S *&) const =0; }; template @@ -198,7 +201,7 @@ public: Gets an object of a specific type from the collection. */ template - T &get(const std::string &name) const + T *get(const std::string &name) const { typedef typename RemoveConst::Type NCT; @@ -219,7 +222,7 @@ public: invoked. */ template - T &get(const std::string &name) + T *get(const std::string &name) { typedef typename RemoveConst::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(*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(d); return *d; } + } throw KeyError("Item '"+name+"' not found in collection"); } diff --git a/source/loader.h b/source/loader.h index 8d26a41..acc84fe 100644 --- a/source/loader.h +++ b/source/loader.h @@ -151,6 +151,23 @@ private: }; +template +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).*func)(st.args[0].get(), st.args[1].get(), st.args[2].get(), st.args[3].get(), st.args[4].get()); + } +private: + FuncType func; +}; + + template 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(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 into a variable of the loaded object. */ -- 2.43.0