Boost logo

Boost Users :

From: Nindi Singh (nindi73_at_[hidden])
Date: 2006-11-01 20:06:12


OK did it . <Phactory.h> #ifndef PHACTORY_HEADER_GUARD #define PHACTORY_HEADER_GUARD #include<string> #include<map> #include<cassert> #include<boost/shared_ptr.hpp> #include<boost/variant.hpp> #include<boost/utility.hpp> #include<boost/static_assert.hpp> #include<boost/mpl/size.hpp> #include<boost/mpl/list.hpp> #include<boost/mpl/at.hpp> template<unsigned long i> struct unsigned_long {enum {value=i};}; template<class BaseClass> struct PhRegistraBase { typedef typename boost::make_variant_over<typename BaseClass::variant_type_list::type>::type variant; typedef std::map<std::string,variant> ParameterMap; virtual boost::shared_ptr<BaseClass> RetrieveObject(const std::string &theKey,const ParameterMap& theMap )const=0; }; template<class BaseClass> class Phactory { public: typedef typename boost::make_variant_over<typename BaseClass::variant_type_list::type>::type variant; typedef std::map<std::string,variant> ParameterMap; bool Register(const std::string &theKey, const PhRegistraBase<BaseClass>* theRegistra){ return theInnerMap.insert(InnerMap::value_type(theKey,theRegistra)).second; } boost::shared_ptr<BaseClass> RetrieveObject(const std::string &id, const ParameterMap & theMap)const { InnerMapIterator theIterator (theInnerMap.find(id)); if(theIterator==theInnerMap.end())return boost::shared_ptr<BaseClass>(static_cast<BaseClass *>(0)); return theIterator->second->RetrieveObject(id,theMap); } private: typedef typename std::map<std::string,const PhRegistraBase<BaseClass> *> InnerMap; typedef typename std::map<std::string,const PhRegistraBase<BaseClass> *>::const_iterator InnerMapIterator; std::map<std::string,const PhRegistraBase<BaseClass> *> theInnerMap; }; #define CPARAM_1 boost::get<const boost::mpl::at_c<signature,0>::type &>(theMap.find(theVarNames[0])->second) #define CPARAM_2 CPARAM_1, boost::get<const boost::mpl::at_c<signature,1>::type &>(theMap.find(theVarNames[1])->second) #define CPARAM_3 CPARAM_2, boost::get<const boost::mpl::at_c<signature,2>::type &>(theMap.find(theVarNames[2])->second) #define CPARAM_4 CPARAM_3, boost::get<const boost::mpl::at_c<signature,3>::type &>(theMap.find(theVarNames[3])->second) #define CPARAM_5 CPARAM_4, boost::get<const boost::mpl::at_c<signature,4>::type &>(theMap.find(theVarNames[4])->second) #define CPARAM_6 CPARAM_5, boost::get<const boost::mpl::at_c<signature,5>::type &>(theMap.find(theVarNames[5])->second) #define CPARAM_7 CPARAM_6, boost::get<const boost::mpl::at_c<signature,6>::type &>(theMap.find(theVarNames[6])->second) #define CPARAM_8 CPARAM_7, boost::get<const boost::mpl::at_c<signature,7>::type &>(theMap.find(theVarNames[7])->second) #define CPARAM_9 CPARAM_8, boost::get<const boost::mpl::at_c<signature,8>::type &>(theMap.find(theVarNames[8])->second) #define CPARAM_10 CPARAM_9, boost::get<const boost::mpl::at_c<signature,9>::type &>(theMap.find(theVarNames[9])->second) #define INNER_RETRIVE_OBJECT(Nb) \ template<> boost::shared_ptr<BaseClass> InnerRetrieveObject< Nb >(const std::string &theKey,const ParameterMap& theMap)const{ \ CheckMap(theMap); \ return boost::shared_ptr<BaseClass>(new DerivedClass( CPARAM_##Nb ) \ ); \ } template < class BaseClass, class DerivedClass > class PhRegistra:public PhRegistraBase<BaseClass>{ public: typedef typename DerivedClass::constructor_signature_typelist signature; typedef typename boost::make_variant_over<typename BaseClass::variant_type_list::type>::type variant; typedef std::map<std::string,variant> ParameterMap; enum {ssize = boost::mpl::size<signature>::value}; template<unsigned long i> PhRegistra(const std::string &theKey, const char *theVariableNames[],const unsigned_long<i> *p=0) { BOOST_STATIC_ASSERT(i==ssize); // Must have ONE variable name for each paramter of the constructor for(unsigned long i(0);i<ssize;++i) theVarNames[i]=std::string(theVariableNames[i]); Singleton<Phactory<BaseClass> >::instance().Register(theKey,this); } boost::shared_ptr<BaseClass> RetrieveObject(const std::string &theKey,const ParameterMap& theMap)const{ return InnerRetrieveObject<ssize>(theKey,theMap); } template<int i> boost::shared_ptr<BaseClass> InnerRetrieveObject(const std::string &theKey,const ParameterMap&)const; INNER_RETRIVE_OBJECT(1) INNER_RETRIVE_OBJECT(2) INNER_RETRIVE_OBJECT(3) INNER_RETRIVE_OBJECT(4) INNER_RETRIVE_OBJECT(5) INNER_RETRIVE_OBJECT(6) INNER_RETRIVE_OBJECT(7) INNER_RETRIVE_OBJECT(8) INNER_RETRIVE_OBJECT(9) INNER_RETRIVE_OBJECT(10) private: void CheckMap(const ParameterMap& theMap)const { assert(theMap.size()==ssize); for(unsigned long i(0);i<ssize;++i)assert(theMap.find(theVarNames[i])!=theMap.end()); } std::string theVarNames[ssize]; }; #define PARAM_NAMES(n) n , static_cast<unsigned_long<sizeof(n)/sizeof(char*)> *>(0) #endif ----------------- end of Phactory.h <main,cpp> #include<vector> #include<iostream> #include"Phactory.h" using namespace std; template<class Object> //Quick liitle singletone just to demonstrate class Singleton { public: static Object & instance(){static Object theObject;return theObject;} virtual ~Singleton(){} private: Singleton(); Singleton(const Singleton<Object> & illegal); Singleton<Object> & operator=(const Singleton<Object> & illegal){return *this;} }; struct Dummy{}; struct Base { typedef boost::mpl::list<double,int,unsigned long,std::string,std::vector<double>,float,Dummy> variant_type_list; Base(){} virtual void f()const=0; virtual ~Base(){}; }; struct Derived :public Base { typedef boost::mpl::list<double,int,std::string,std::vector<double> > constructor_signature_typelist; Derived(double x_,int n_,const std::string &s_,const std::vector<double>&v_): x(x_),n(n_),s(s_),v(v_){} virtual void f()const{ cout << "My Double is " << x << "\n" << "My int is " << n << "\n" << "My String is " << s << "\n" << "My Vector Size is " << v.size() << "\n"; } private: double x; int n; std::string s; std::vector<double> v; }; namespace { const char * theVarNames[]={"Double","Int","String","Vector"}; PhRegistra<Base,Derived> thePhRegistra(std::string("DerivedObject"),PARAM_NAMES(theVarNames)); } int main() { std::map<std::string,typename boost::make_variant_over<typename Base::variant_type_list::type>::type> theMap; theMap["Double"]=1.0; theMap["Int"]=1; theMap["String"]="hello"; theMap["Vector"]=std::vector<double>(10); boost::shared_ptr<Base> thePtrSM(Singleton<Phactory<Base> >::instance().RetrieveObject("DerivedObject",theMap)); thePtrSM->f(); } ----- Original Message ---- From: Nindi Singh <nindi73_at_[hidden]> To: boost-users_at_[hidden] Sent: Wednesday, 1 November, 2006 8:59:31 PM Subject: Re: [Boost-users] Boost ROCKS !!!!! Cool ! Actualy I am now working another factory implementation. In the new implementation, the Base Class will hold a typedef for a Boost Variant, and then the derived objects can be instantiated by the factory by being given a std::map of the variants and stripping out the values to make a call to the constructor of the derived class. The ONLY intrusion on the classes would be a typelist in the Base class to type the appropriate Boost::Variant and a typelist in the derived class identifing the signature of the constructor to be called by the factory, similar to the factory i have posted previously. The MPL really is VERY cool, and I think I have JUST touched the surface !!!. In fact I put my order in for 'C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond' at Amazon this afternoon !!!! ----- Original Message ---- From: Sohail Somani <s.somani_at_[hidden]> To: boost-users_at_[hidden] Sent: Wednesday, 1 November, 2006 8:46:28 PM Subject: Re: [Boost-users] Boost ROCKS !!!!! > -----Original Message----- > From: boost-users-bounces_at_[hidden] > [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Nindi Singh > > For the past few months I have been making more and more use > of Boost, in fact I would say becoming more and more reliant > on Boost, every so often introducing myslef to a new library. > But discovering the MPL, well that was awsome. The first time > I applied it was to implement a factory. I would NEVR have > though of doing it this way WITHOUT the MPL. Any comments on > my use ( or indeed abuse !) of Boost would be more than apprieciated. [snip code] Actually, I've been thinking of doing something similar and I am also interested in what people say! PS: Boost does rock _______________________________________________ Boost-users mailing list Boost-users_at_[hidden] http://lists.boost.org/mailman/listinfo.cgi/boost-users All new Yahoo! Mail "The new Interface is stunning in its simplicity and ease of use." - PC Magazine _______________________________________________ Boost-users mailing list Boost-users_at_[hidden] http://lists.boost.org/mailman/listinfo.cgi/boost-users Send instant messages to your online friends http://uk.messenger.yahoo.com



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net