FamilyFactory.h
Go to the documentation of this file.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 static FamilyFactory& getRegistry() { static FamilyFactory registry; return registry; }
00053
00054
00055 template<typename N> void getTypeNames(std::set<N>& types) const;
00056
00057
00058 unsigned int getNumTypes() const { return factories.size(); }
00059
00060
00061 template<typename T> const NameT& registerType(const NameT& type) { return registerFactory(type,new FactoryT<T>); }
00062
00063
00064 const NameT& registerFactory(const NameT& type, FactoryBaseT* f);
00065
00066
00067
00068 FamilyT* create(const NameT& type) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)() : NULL; }
00069
00070
00071
00072 template<typename A1>
00073 FamilyT* create(const NameT& type, const A1& a1) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)(a1) : NULL; }
00074
00075
00076
00077 template<typename A1, typename A2>
00078 FamilyT* create(const NameT& type, const A1& a1, const A2& a2) const { FactoryBaseT * f=lookupFactory(type); return f ? (*f)(a1,a2) : NULL; }
00079
00080
00081
00082 template<typename A1, typename A2, typename A3>
00083 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; }
00084
00085 protected:
00086
00087 FactoryBaseT* lookupFactory(const NameT& type) const;
00088
00089
00090 typedef std::map<NameT,FactoryBaseT*> factories_t;
00091 factories_t factories;
00092 };
00093
00094 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00095 template<typename N>
00096 void FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::getTypeNames(std::set<N>& types) const {
00097 types.clear();
00098 for(typename factories_t::const_iterator it=factories.begin(); it!=factories.end(); ++it)
00099 types.insert(it->first);
00100 }
00101
00102 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00103 const NameT& FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::registerFactory(const NameT& type, FactoryBaseT* f) {
00104 typename factories_t::const_iterator it=factories.find(type);
00105 if(it!=factories.end()) {
00106 std::cerr << "WARNING: Type " << type << " was already registered! Overwriting previous..." << std::endl;
00107 delete it->second;
00108 }
00109 factories[type]=f;
00110 return type;
00111 }
00112
00113 template<class FamilyT, typename NameT, class FactoryBaseT, template<class U> class FactoryT>
00114 FactoryBaseT* FamilyFactory<FamilyT,NameT,FactoryBaseT,FactoryT>::lookupFactory(const NameT& type) const {
00115 typename factories_t::const_iterator it=factories.find(type);
00116 if(it==factories.end())
00117 return NULL;
00118 return it->second;
00119 }
00120
00121
00122
00123
00124
00125
00126 #endif