OK did it .
#ifndef PHACTORY_HEADER_GUARD
#define PHACTORY_HEADER_GUARD
#include<string>
#include<map>
#include<cassert>
#include
#include
#include
#include
#include
#include
#include
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::mapstd::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::mapstd::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(0));
return theIterator->second->RetrieveObject(id,theMap);
}
private:
typedef typename std::map InnerMap;
typedef typename std::map::const_iterator InnerMapIterator;
std::map theInnerMap;
};
#define CPARAM_1 boost::get::type &>(theMap.find(theVarNames[0])->second)
#define CPARAM_2 CPARAM_1, boost::get::type &>(theMap.find(theVarNames[1])->second)
#define CPARAM_3 CPARAM_2, boost::get::type &>(theMap.find(theVarNames[2])->second)
#define CPARAM_4 CPARAM_3, boost::get::type &>(theMap.find(theVarNames[3])->second)
#define CPARAM_5 CPARAM_4, boost::get::type &>(theMap.find(theVarNames[4])->second)
#define CPARAM_6 CPARAM_5, boost::get::type &>(theMap.find(theVarNames[5])->second)
#define CPARAM_7 CPARAM_6, boost::get::type &>(theMap.find(theVarNames[6])->second)
#define CPARAM_8 CPARAM_7, boost::get::type &>(theMap.find(theVarNames[7])->second)
#define CPARAM_9 CPARAM_8, boost::get::type &>(theMap.find(theVarNames[8])->second)
#define CPARAM_10 CPARAM_9, boost::get::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::mapstd::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::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 *>(0)
#endif
----------------- end of Phactory.h
#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 variant_type_list;
Base(){}
virtual void f()const=0;
virtual ~Base(){};
};
struct Derived :public Base {
typedef boost::mpl::list 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 thePhRegistra(std::string("DerivedObject"),PARAM_NAMES(theVarNames));
}
int main() {
std::map theMap;
theMap["Double"]=1.0;
theMap["Int"]=1;
theMap["String"]="hello";
theMap["Vector"]=std::vector<double>(10);
boost::shared_ptr<Base>
thePtrSM(Singleton::instance().RetrieveObject("DerivedObject",theMap));
thePtrSM->f();
}
----- Original Message ----
From: Nindi Singh
To: boost-users@lists.boost.org
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
To: boost-users@lists.boost.org
Sent: Wednesday, 1 November, 2006 8:46:28 PM
Subject: Re: [Boost-users] Boost ROCKS !!!!!
-----Original Message-----
From: boost-users-bounces@lists.boost.org
[mailto:boost-users-bounces@lists.boost.org] 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@lists.boost.org
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@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Send instant messages to your online friends http://uk.messenger.yahoo.com