00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __PEEKABOT_FACTORY_HH
00010 #define __PEEKABOT_FACTORY_HH
00011
00012
00013
00014 #include <stdexcept>
00015 #include <map>
00016
00017
00018
00019 namespace peekabot
00020 {
00021
00029 template<class IdentifierType, class ProductType>
00030 class DefaultFactoryError
00031 {
00032 protected:
00033 static ProductType *on_unknown_type(const IdentifierType &id)
00034 {
00035 throw std::runtime_error("Unknown object type passed to Factory");
00036 }
00037 };
00038
00039
00040
00090 template
00091 <
00092 class AbstractProduct,
00093 class IdentifierType,
00094 class ProductCreator = AbstractProduct *(*)(),
00095 template<typename, class> class FactoryErrorPolicy = DefaultFactoryError
00096 >
00097 class Factory
00098 : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
00099 {
00100 public:
00101 typedef AbstractProduct AbstractProductType;
00102 typedef const IdentifierType IdentifierTypeType;
00103 typedef ProductCreator ProductCreatorType;
00104
00105 AbstractProduct *instantiate(const IdentifierType &id) const
00106 {
00107 typename CreatorMap::const_iterator it = m_registry.find(id);
00108 if( it != m_registry.end() )
00109 return it->second();
00110
00111 return on_unknown_type(id);
00112 }
00113
00114 bool register_product(const IdentifierType &id,
00115 ProductCreator creator) throw()
00116 {
00117 return m_registry.insert(
00118 typename CreatorMap::value_type(id, creator)).second;
00119 }
00120
00121 bool deregister_product(const IdentifierType &id) throw()
00122 {
00123 return m_registry.erase(id) == 1;
00124 }
00125
00126 void deregister_all() throw()
00127 {
00128 m_registry.clear();
00129 }
00130
00131 private:
00132 typedef std::map<IdentifierType, ProductCreator> CreatorMap;
00133 CreatorMap m_registry;
00134 };
00135
00136
00137 }
00138
00139
00140
00141 #endif // __PEEKABOT_FACTORY_HH