Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Templates & abstraction question

Reply
Thread Tools

Templates & abstraction question

 
 
AzizMandar
Guest
Posts: n/a
 
      11-09-2006
There is probably a better way to do this and if so I'm just as happy
to see that way.


I have a program where I have factories that each create various
objects abstracted from a base class. The Factories all have a base
class as well for the objects to point back to.

So I have

class CBFactory{
public:
CBFactory();
~CBFactory();
}

class CBObject{
CBFactory* m_home;
public:
CBObject();
~CBObject();
}

class SillyObjectublic CBObject{
//Code that makes it unique
public:
SillyObject(CBFactory*); //Set the m_home on creation
~SillyObject();

}

class SillyFactoryublic CBFactory,public singleton{
public:
SillyFactory();
~SillyFactory();
CBObject* MakeObj(){
SillyObject* NewObj = new SillyObject(this);
return NewObj;
}
}


Now Singleton just adds my singleton elements (It works a little
diffrant but I included it to show the multiple inheritance I use)

Right now I have a lot of member functions like MakeObj() and they are
so similar in each factory that it would be nice to template them. The
problem is I don't know if there is a way to let the template know that
the dependant class type (SillyObject in this case) is derived from
CBObjects since that is what I am returning a pointer to. I could
probably explicit cast it and tell the compiler to ignore the casting
but I figure there could be a more type safe way to do it.

 
Reply With Quote
 
 
 
 
amparikh@gmail.com
Guest
Posts: n/a
 
      11-09-2006

AzizMandar wrote:
> There is probably a better way to do this and if so I'm just as happy
> to see that way.
>
>
> I have a program where I have factories that each create various
> objects abstracted from a base class. The Factories all have a base
> class as well for the objects to point back to.
>
> So I have
>
> class CBFactory{
> public:
> CBFactory();
> ~CBFactory();
> }
>
> class CBObject{
> CBFactory* m_home;
> public:
> CBObject();
> ~CBObject();
> }
>
> class SillyObjectublic CBObject{
> //Code that makes it unique
> public:
> SillyObject(CBFactory*); //Set the m_home on creation
> ~SillyObject();
>
> }
>
> class SillyFactoryublic CBFactory,public singleton{
> public:
> SillyFactory();
> ~SillyFactory();
> CBObject* MakeObj(){
> SillyObject* NewObj = new SillyObject(this);
> return NewObj;
> }
> }
>
>
> Now Singleton just adds my singleton elements (It works a little
> diffrant but I included it to show the multiple inheritance I use)
>
> Right now I have a lot of member functions like MakeObj() and they are
> so similar in each factory that it would be nice to template them. The
> problem is I don't know if there is a way to let the template know that
> the dependant class type (SillyObject in this case) is derived from
> CBObjects since that is what I am returning a pointer to. I could
> probably explicit cast it and tell the compiler to ignore the casting
> but I figure there could be a more type safe way to do it.


so what's the problem in doing the following ?

template<typename T>
T* SillyFactory::MakeObj(){
T* NewObj = new T(this);
return NewObj;
}

Make the MakeObj function to be a static function and then you can use.

SillyObject* p = SillyFactory::Create<SillyObject>();

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      11-09-2006
AzizMandar wrote:
> There is probably a better way to do this and if so I'm just as happy
> to see that way.
>
>
> I have a program where I have factories that each create various
> objects abstracted from a base class. The Factories all have a base
> class as well for the objects to point back to.
>
> So I have
>
> class CBFactory{
> public:
> CBFactory();
> ~CBFactory();
> }
>
> class CBObject{
> CBFactory* m_home;
> public:
> CBObject();
> ~CBObject();
> }
>
> class SillyObjectublic CBObject{
> //Code that makes it unique
> public:
> SillyObject(CBFactory*); //Set the m_home on creation
> ~SillyObject();
>
> }
>
> class SillyFactoryublic CBFactory,public singleton{
> public:
> SillyFactory();
> ~SillyFactory();
> CBObject* MakeObj(){
> SillyObject* NewObj = new SillyObject(this);
> return NewObj;
> }
> }
>
>
> Now Singleton just adds my singleton elements (It works a little
> diffrant but I included it to show the multiple inheritance I use)
>
> Right now I have a lot of member functions like MakeObj() and they are
> so similar in each factory that it would be nice to template them. The
> problem is I don't know if there is a way to let the template know that
> the dependant class type (SillyObject in this case) is derived from
> CBObjects since that is what I am returning a pointer to. I could
> probably explicit cast it and tell the compiler to ignore the casting
> but I figure there could be a more type safe way to do it.


Check out the factory and singleton classes described in _Modern C++
Design_ by Alexandrescu. The code can be downloaded for free from:

http://sourceforge.net/projects/loki-lib/

You can see an example of the Singleton usage here:

http://groups.google.com/group/comp....adedc5b34ee23d

The factory allows you to register a creation function and then create
using some ID. It's quite clever and quite useful!

Cheers! --M

 
Reply With Quote
 
AzizMandar
Guest
Posts: n/a
 
      11-09-2006
>so what's the problem in doing the following ?
>
> template<typename T>
> T* SillyFactory::MakeObj(){
> T* NewObj = new T(this);
> return NewObj;
>
> }Make the MakeObj function to be a static function and then you can use.
>
> SillyObject* p = SillyFactory::Create<SillyObject>();


The MakeObj() is no longer returning type CBObject* it is now
returning the type T* (so SillyObject if I did
SillyFactory<SillyObject>)

When I would go to call CBOFactory::NewObj() from SillyFactory the
return type would not match. I don't even think it would compile
because the arguments match and return types don't.

In my code I don't know that SIllyFactory or SillyObject will be used
(I want to make what ever ones I need without changing the core
program) So I can only deal with CBObject and CBOFactory. I can just
explicitly override the function MakeObj() and make it virtual in
CBOFactory but I am copying and pasting code every time and only
changing the inherited CBObject class. I was hoping for a template
solution but the reliance on the type T to be inherited from CBObject
is causing a bit of a problem. Of course I guess I can explicit cast T
to CBObject for the return type but if it was ever of a class not
inherited from CBObject that would be REALLY bad (hence why that
process would be 'EVIL')

 
Reply With Quote
 
AzizMandar
Guest
Posts: n/a
 
      11-09-2006
> Check out the factory and singleton classes described in _Modern C++
> Design_ by Alexandrescu. The code can be downloaded for free from:
>
> http://sourceforge.net/projects/loki-lib/
>
> You can see an example of the Singleton usage here:
>
> http://groups.google.com/group/comp....adedc5b34ee23d
>
> The factory allows you to register a creation function and then create
> using some ID. It's quite clever and quite useful!
>
> Cheers! --M


Thanks. I'll look into that. The Singleton is very similar to one I
use so I'm happy to see I'm at least doing that right. I have read
things similar to what you describe about the factory and was trying to
avoid that in my program design (ID and lookup) but it is safe and it
can be templated much easier. I'm just worried about performance of an
ID lookup routine rather than a straight pointer call. I'm not worried
about losing pointer or trying to call a deleted pointer (My garbage
class is working well for that) but I will look over the information
and maybe redesign some of my code.

Thanks again

 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      11-09-2006

AzizMandar wrote:
> There is probably a better way to do this and if so I'm just as happy
> to see that way.
>
>
> I have a program where I have factories that each create various
> objects abstracted from a base class. The Factories all have a base
> class as well for the objects to point back to.
>
> So I have
>
> class CBFactory{
> public:
> CBFactory();
> ~CBFactory();
> }
>
> class CBObject{
> CBFactory* m_home;
> public:
> CBObject();
> ~CBObject();
> }
>
> class SillyObjectublic CBObject{
> //Code that makes it unique
> public:
> SillyObject(CBFactory*); //Set the m_home on creation
> ~SillyObject();
>
> }
>
> class SillyFactoryublic CBFactory,public singleton{
> public:
> SillyFactory();
> ~SillyFactory();
> CBObject* MakeObj(){
> SillyObject* NewObj = new SillyObject(this);
> return NewObj;
> }
> }
>


Your class definitions need semicolons. MakeObj() should be static. Any
base class you allocate via new/delete needs a vitual d~tor (MakeObj()
is returning a base ptr). The goal is to isolate the singleton's
interface so only the static creator function is accessible. You should
prefer smart pointers over new/delete.

>
> Now Singleton just adds my singleton elements (It works a little
> diffrant but I included it to show the multiple inheritance I use)
>
> Right now I have a lot of member functions like MakeObj() and they are
> so similar in each factory that it would be nice to template them. The
> problem is I don't know if there is a way to let the template know that
> the dependant class type (SillyObject in this case) is derived from
> CBObjects since that is what I am returning a pointer to. I could
> probably explicit cast it and tell the compiler to ignore the casting
> but I figure there could be a more type safe way to do it.


 
Reply With Quote
 
Nindi73@yahoo.co.uk
Guest
Posts: n/a
 
      11-10-2006
You are more than welcome to look at my factory code, it makes heavy
use of Boost ( which is a good thing). There are actualy 3 factories.
One returning new objects derived from a base class, and the base class
must have a typelist to identify the constructor to be used by the
factory.
The second returns a reference to a shared, static object, again the
base class must have a typelist identifying the signature of the
constructor.

The third Factory produces derived objects of a given base class, but
queries the derived objects for a typelist so it can work out which
consructor to call to produce the object.

I'll first pate in the main.cpp, it shoes example code using the
factory, followed by the factory code.


-------------------------------------------------------------------------------------------------------------------------------
<main.cpp>
#include<vector>
#include<iostream>
#include"Factory.h"
#include"Phactory.h"

using namespace std;

struct MyClassVoid {
typedef boost::mpl::list<> Constructor_TypeList;
MyClassVoid(){}
virtual void f()const=0;
virtual ~MyClassVoid(){};
};
struct MyClassVoidDerived ublic MyClassVoid {
MyClassVoidDerived(){}
virtual void f()const{cout << " I am in MyClassVoidDerived \n";}
virtual ~MyClassVoidDerived(){};
};

namespace {
Registra<MyClassVoid,MyClassVoidDerived>
theRegistraVoid(std::string("MyClassVoidDerived")) ;
}

struct MyClassDouble {
typedef boost::mpl::list<double> Constructor_TypeList;
typedef boost::mpl::list<double> variant_type_list;
MyClassDouble(double){}
virtual void f(){cout << " I am in MyClassDouble \n";}
virtual ~MyClassDouble(){};
};
struct MyClassDoubleDerived ublic MyClassDouble {
typedef boost::mpl::list<double> constructor_signature_typelist;
MyClassDoubleDerived(double x):MyClassDouble(x){}
virtual void f(){cout << " I am in MyClassDoubleDerived \n";}
virtual ~MyClassDoubleDerived(){};
};
namespace {
Registra<MyClassDouble,MyClassDouble>
theRegistra(std::string("MyClassDouble"));
Registra<MyClassDouble,MyClassDoubleDerived>
theRegistraD(std::string("MyClassDoubleDerived"));
}

struct MyClassMultiple {
typedef
boost::mpl::list<std::string,std::vector<double>,d ouble,MyClassDoubleDerived
> Constructor_TypeList;

MyClassMultiple(std::string,std::vector<double>,do uble,MyClassDoubleDerived){}
virtual void f(){cout << " I am in MyClassMultiple \n";}
virtual ~MyClassMultiple(){};
};

namespace {
Registra<MyClassMultiple,MyClassMultiple>
theRegistraM(std::string("MyClassMultiple"));
StaticRegistra<MyClassMultiple,MyClassMultiple>
theStaticRegistraM(std::string("MyClassMultiple"), std::string("String"),std::vector<double>(2),1.0,M yClassDoubleDerived(1.0));
}

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 ublic Base {
typedef boost::mpl::list<double,int,std::string,std::vecto r<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_N AMES(theVarNames));
}


int main() {

boost::shared_ptr<MyClassVoid>
thePtrVoid(Singleton<Factory<MyClassVoid>
>::instance().RetrieveObject("MyClassVoidDerived") );

thePtrVoid->f();


boost::shared_ptr<MyClassDouble>
thePtrDoubleDerived(Singleton<Factory<MyClassDoubl e>
>::instance().RetrieveObject("MyClassDoubleDerived ",1.0));

thePtrDoubleDerived->f();

boost::shared_ptr<MyClassDouble>
thePtrDouble(Singleton<Factory<MyClassDouble>
>::instance().RetrieveObject("MyClassDouble",1.0)) ;

thePtrDouble->f();

boost::shared_ptr<MyClassMultiple>
thePtrM(Singleton<Factory<MyClassMultiple>
>::instance().RetrieveObject("MyClassMultiple",std ::string("String"),std::vector<double>(2),1.0,MyCl assDoubleDerived(1.0)));

thePtrM->f();

boost::shared_ptr<MyClassMultiple>
thePtrSM(Singleton<StaticFactory<MyClassMultiple>
>::instance().RetrieveObject("MyClassMultiple")) ;

thePtrSM->f();

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>
thePtrPhM(Singleton<Phactory<Base>
>::instance().RetrieveObject("DerivedObject",theMa p));

thePtrPhM->f();


}
-------------------------------------------------------------------------------------------------------------------------------------
The Factory code

---------------------------------------------------------------------------
<Singleton.h>
#ifndef SINGLETON_HEADER_GUARD
#define SINGLETON_HEADER_GUARD
#include <boost/utility.hpp>

template<class Object>
struct Singleton :boost::noncopyable{
public:

static Object & instance(){static Object theObject;return theObject;}
virtual ~Singleton(){}

};
#endif
--------------------------------------------------------------------------------------

<Factory.h>
#ifndef FACTORY_HEADER_GUARD
#define FACTORY_HEADER_GUARD

#include<string>
#include<map>

#include"Singleton.h"

#include<boost/shared_ptr.hpp>
#include<boost/mpl/size.hpp>
#include<boost/mpl/list.hpp>
#include<boost/mpl/at.hpp>

#include<boost/preprocessor/repetition.hpp>
#include<boost/preprocessor/arithmetic/sub.hpp>

#ifndef MAX_FACTORIES
#define MAX_FACTORIES 10
#endif

// One Registration object per class in a hireachy, this is the
template blue print for the base classes of
// the registration objects

template
<
class BaseClass,
typename Key = std::string,
unsigned long = boost::mpl::size<typename
BaseClass::Constructor_TypeList>::value
>

struct RegistraBase {};

// This is the template blue print for the concrete classes of
// the registration objects

template
<
class BaseClass,
class Derived,
typename Key = std::string,
unsigned long n = boost::mpl::size<typename
BaseClass::Constructor_TypeList>::value
>

struct Registra ublic RegistraBase<BaseClass,Key,n>{};

// This is the factory template blue print of the Factory class

template
<
class BaseClass,
typename Key = std::string ,
unsigned long n = boost::mpl::size<typename
BaseClass::Constructor_TypeList>::value
>

class Factory {};

//Helper Macros
#define PARAM(z,Nb,data) typename boost::mpl::at_c<typename
BaseClass::Constructor_TypeList,Nb>::type P##Nb

#define REGISTRABASE(z,Nb,data) \
template<class BaseClass,typename Key> struct
RegistraBase<BaseClass,Key,Nb> { \
virtual boost::shared_ptr<BaseClass>
RetrieveObject(BOOST_PP_ENUM(Nb,PARAM,~))const=0; \
};

BOOST_PP_REPEAT(MAX_FACTORIES,REGISTRABASE,~)


#define FACTORY(z,Nb,data) \
template \
< \
class BaseClass, \
typename Key \
> \

class Factory<BaseClass,Key,Nb> { \
public: \
bool Register(const Key & theKey,RegistraBase<BaseClass,Key,Nb>
*theRegistra){ \
return
theInnerMap.insert(InnerMap::value_type(theKey,the Registra)).second; \
} \
\
boost::shared_ptr<BaseClass> RetrieveObject(const Key &id
BOOST_PP_COMMA_IF(Nb) BOOST_PP_ENUM(Nb,PARAM,~))const { \
InnerMapIterator theIterator (theInnerMap.find(id)); \
if(theIterator==theInnerMap.end())return
boost::shared_ptr<BaseClass>(static_cast<BaseClass *>(0)); \
return theIterator->second->RetrieveObject(
BOOST_PP_ENUM_PARAMS(Nb,P)); \
} \
private: \
typedef typename std::map<Key,RegistraBase<BaseClass,Key,Nb> *>
InnerMap; \
typedef typename std::map<Key,RegistraBase<BaseClass,Key,Nb>
*>::const_iterator InnerMapIterator; \
std::map<Key,RegistraBase<BaseClass,Key,Nb> *>
theInnerMap; \
};

BOOST_PP_REPEAT(MAX_FACTORIES,FACTORY,~)

// The macro defintions of the Registration Objects

#define REGISTRA(z,Nb,data) \
template<class BaseClass,class Derived,typename
Key> \
struct Registra<BaseClass,Derived,Key,Nb>ublic
RegistraBase<BaseClass,Key,Nb> { \
Registra(const Key & theKey){Singleton<Factory<BaseClass,Key,Nb>
>::instance().Register(theKey,this);} \

boost::shared_ptr<BaseClass>
RetrieveObject(BOOST_PP_ENUM(Nb,PARAM,~))const \
{return boost::shared_ptr<BaseClass>(new Derived(
BOOST_PP_ENUM_PARAMS(Nb,P)));} \
virtual ~Registra(){} \
};

BOOST_PP_REPEAT(MAX_FACTORIES,REGISTRA,~)

#undef MAX_FACTORIES
#undef PARAM
#undef REGISTRA
#undef REGISTRABASE
#undef FACTORY

#include"StaticFactory.h"

#endif
-----------------------------------------------------------------------------------------------------------------------------


<StaticFactory.h>
#ifndef STATIC_FACTORY_HEADER_GUARD
#define STATIC_FACTORY_HEADER_GUARD
#include<string>
#include<map>

#include"Singleton.h"

#include<boost/shared_ptr.hpp>
#include<boost/mpl/size.hpp>
#include<boost/mpl/list.hpp>
#include<boost/mpl/at.hpp>

#include<boost/preprocessor/repetition.hpp>
#include<boost/preprocessor/arithmetic/sub.hpp>

#ifndef MAX_STATIC_FACTORIES
#define MAX_STATIC_FACTORIES 10
#endif


template
<
class BaseClass,
typename Key = std::string
>

struct StaticRegistraBase {
virtual boost::shared_ptr<BaseClass> RetrieveObject()const=0;
};

template
<
class BaseClass,
class Derived,
typename Key = std::string,
unsigned long n = boost::mpl::size<typename
BaseClass::Constructor_TypeList>::value
>

struct StaticRegistra ublic StaticRegistraBase<BaseClass,Key>{};

template
<
class BaseClass,
typename Key=std::string
>

class StaticFactory {
public:
bool Register(const Key & theKey,StaticRegistraBase<BaseClass,Key>
*theRegistra){
return
theInnerMap.insert(InnerMap::value_type(theKey,the Registra)).second;
}
boost::shared_ptr<BaseClass> RetrieveObject(const Key &id )const {
InnerMapIterator theIterator (theInnerMap.find(id));
if(theIterator==theInnerMap.end())return
boost::shared_ptr<BaseClass>(static_cast<BaseClass *>(0));
return theIterator->second->RetrieveObject();
}

private:
typedef typename std::map<Key,StaticRegistraBase<BaseClass,Key> *>
InnerMap;
typedef typename std::map<Key,StaticRegistraBase<BaseClass,Key>
*>::const_iterator InnerMapIterator;
std::map<Key,StaticRegistraBase<BaseClass,Key> *> theInnerMap;

};

//Helper Macros
#define PARAM(z,Nb,data) typename boost::mpl::at_c<typename
BaseClass::Constructor_TypeList,Nb>::type P##Nb

#define STATICREGISTRA(z,Nb,data) template<class BaseClass,class
Derived,typename Key> \
struct StaticRegistra<BaseClass,Derived,Key, Nb >ublic
StaticRegistraBase<BaseClass,Key> \
{ \
StaticRegistra(const Key & theKey BOOST_PP_COMMA_IF(Nb)
BOOST_PP_ENUM(Nb,PARAM,~)): \
theObjectPtr(new Derived(BOOST_PP_ENUM_PARAMS(Nb,P))) \
{ \
Singleton<StaticFactory<BaseClass,Key>
>::instance().Register(theKey,this); \

} \
boost::shared_ptr<BaseClass> RetrieveObject()const{return
theObjectPtr;} \
virtual ~StaticRegistra(){} \
private: \
boost::shared_ptr<BaseClass> theObjectPtr; \
};

BOOST_PP_REPEAT(MAX_STATIC_FACTORIES,STATICREGISTR A,~)

#undef MAX_STATIC_FACTORIES
#undef PARAM
#undef STATICREGISTRA

#endif
--------------------------------------------------------------------------------------------------------------


<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>

#include<boost/preprocessor/repetition.hpp>


#ifndef MAX_PHACTORIES
#define MAX_PHACTORIES 10
#endif



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,the Registra)).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 PARAM(z,Nb,data) boost::get<const boost::mpl::at_c<signature,
Nb >::type &>(theMap.find(theVarNames[Nb])->second)

#define INNER_RETRIVE_OBJECT(z,Nb,data) \
template<> boost::shared_ptr<BaseClass> InnerRetrieveObject< Nb
>(const std::string &theKey,const ParameterMap& theMap) \

const{ \
CheckMap(theMap); \
return boost::shared_ptr<BaseClass>(new DerivedClass(
BOOST_PP_ENUM(Nb,PARAM,~) ) \
); \
}



template
<
class BaseClass,
class DerivedClass
>

class PhRegistraublic 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;

BOOST_PP_REPEAT(MAX_PHACTORIES,INNER_RETRIVE_OBJEC T,~)

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)


#undef MAX_PHACTORIES
#undef PARAM
#undef INNER_RETRIVE_OBJECT


#endif
-------------------------------------------------------------------------------------------------------------------------------

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to Specializations of function Templates or Overloading Function templates with Templates ? recover C++ 2 07-25-2006 02:55 AM
PAC (presentation-abstraction-control) question craig C++ 1 03-22-2006 08:03 PM
Monster Templates - Question about Submitting Templates Fred HTML 1 09-26-2005 01:09 AM
HDL Abstraction of Dynamic Logic Alex VHDL 2 09-18-2005 04:00 PM
Templates templates templates JKop C++ 3 07-21-2004 11:44 AM



Advertisments