/* $Id: factory.hh 1604 2008-04-06 11:50:39Z awgn $ */ /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. Nicola Bonelli * ---------------------------------------------------------------------------- */ #ifndef FACTORY_HH #define FACTORY_HH #include #include #include #include #if __GNUC__ >= 4 #include #else #error "g++ compiler not supported" #endif // my generic factory, inspired to that of Andrei Alexandrescu (Modern C++ Design) // namespace generic { template class Memory = memory::New> class factoryElement : public factoryBase { public: std::tr1::shared_ptr alloc() { return std::tr1::shared_ptr( Memory::alloc(), factoryElement::dealloc ); } std::tr1::shared_ptr alloc(const E &e) { return std::tr1::shared_ptr( Memory::alloc(e), factoryElement::dealloc ); } static void dealloc(factoryBase *obj) { Memory::dealloc(static_cast(obj)); } }; template class factory; template class factory { typedef std::map FactoryMap; FactoryMap _M_factory_map; public: factory() : _M_factory_map() {} ~factory() { typename FactoryMap::const_iterator it; for ( it = _M_factory_map.begin() ; it != _M_factory_map.end() ; it++ ) delete it->second; } template std::tr1::shared_ptr operator()(const Key &k, const E &e) { typename FactoryMap::const_iterator it = _M_factory_map.find(k); if ( it == _M_factory_map.end() ) throw std::runtime_error("factory: unknown producer!"); return it->second->alloc(e); } std::tr1::shared_ptr operator()(const Key &k) { typename FactoryMap::const_iterator it = _M_factory_map.find(k); if ( it == _M_factory_map.end() ) throw std::runtime_error("factory: unknown producer!"); return it->second->alloc(); } bool has_key(const Key &k) const { typename FactoryMap::const_iterator it = _M_factory_map.find(k); if ( it == _M_factory_map.end() ) return false; return true; } bool regist(const Key &k, factoryBase *e) { return _M_factory_map.insert(typename FactoryMap::value_type(k, e)).second; } bool unregist(const Key &k) { return _M_factory_map.erase(k) == 1; } }; } #endif /* FACTORY_HH */