00001
00002 #ifndef INCLUDED_FamilyFactory_h_
00003 #define INCLUDED_FamilyFactory_h_
00004
00005 #include "Factories.h"
00006 #include <string>
00007 #include <map>
00008 #include <set>
00009 #include <iostream>
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 template<class FamilyT, typename NameT=std::string, class FactoryBaseT=Factory0Arg<FamilyT>, template<class U> class FactoryT=FactoryBaseT::template Factory>
00030 class FamilyFactory {
00031 public:
00032
00033 typedef FamilyT FamilyType;
00034
00035 typedef NameT NameType;
00036
00037 typedef FactoryBaseT FactoryBaseType;
00038
00039 template<class T> struct FactoryType : FactoryT<T> {};
00040
00041
00042 FamilyFactory() : factories() {}
00043
00044
00045 virtual ~FamilyFactory() {
00046 for(typename factories_t::iterator it=factories.begin(); it!=factories.end(); ++it)
00047 delete it->second;
00048 factories.clear();
00049 }
00050
00051
00052 void getTypeNames(std::set<NameT>& types) const;
00053
00054
00055 unsigned int getNumTypes() const { return factories.size(); }
00056
00057
00058 template<typename T> const NameT& registerType(const NameT& type) { return registerFactory(type,new FactoryT<T>); }
00059
00060
00061 const NameT& registerFactory(const NameT& type, FactoryBaseT* f);
00062
00063
00064
00065 FamilyT* create(const NameT& type) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)() : NULL; }
00066
00067
00068
00069 template<typename A1>
00070 FamilyT* create(const NameT& type, const A1& a1) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)(a1) : NULL; }
00071
00072
00073
00074 template<typename A1, typename A2>
00075 FamilyT* create(const NameT& type, const A1& a1, const A2& a2) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)(a1,a2) : NULL; }
00076
00077
00078
00079 template<typename A1, typename A2, typename A3>
00080 FamilyT* create(const NameT& type, const A1& a1, const A2& a2, const A3& a3) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)(a1,a2,a3) : NULL; }
00081
00082 protected:
00083
00084 FactoryBaseT* lookupFactory(const NameT& type) const;
00085
00086
00087 typedef std::map<NameT,FactoryBaseT*> factories_t;
00088 factories_t factories;
00089 };
00090
00091 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00092 void FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::getTypeNames(std::set<NameT>& types) const {
00093 types.clear();
00094 for(typename factories_t::const_iterator it=factories.begin(); it!=factories.end(); ++it)
00095 types.insert(it->first);
00096 }
00097
00098 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00099 const NameT& FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::registerFactory(const NameT& type, FactoryBaseT* f) {
00100 typename factories_t::const_iterator it=factories.find(type);
00101 if(it!=factories.end()) {
00102 std::cerr << "WARNING: Type " << type << " was already registered! Overwriting previous..." << std::endl;
00103 delete it->second;
00104 }
00105 factories[type]=f;
00106 return type;
00107 }
00108
00109 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00110 FactoryBaseT* FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::lookupFactory(const NameT& type) const {
00111 typename factories_t::const_iterator it=factories.find(type);
00112 if(it==factories.end())
00113 return NULL;
00114 return it->second;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 #endif