//////////////////////////////////////////////////////////////////////// // // Factory allocator // // Author: Stan Seibert <volsung@physics.utexas.edu> // // REVISION HISTORY: // //////////////////////////////////////////////////////////////////////// #ifndef __RAT_Factory__ #define __RAT_Factory__ #include <string> #include <map> namespace RAT { template <class T> class AllocBase { public: virtual T* New() = 0; }; template <class T, class TDerived> class Alloc : public AllocBase<T> { public: virtual T* New() { return new TDerived; }; }; class FactoryUnknownID { public: FactoryUnknownID(const std::string &_id) { id = _id; }; std::string id; }; template <class T> class AllocTable : public std::map< std::string, AllocBase<T>* > { }; template <class T> class Factory { public: T* New(const std::string &id) { if (table.count(id) == 0) throw FactoryUnknownID(id); else return table[id]->New(); }; void Register(const std::string &id, AllocBase<T> *allocator) { table[id] = allocator; }; protected: AllocTable<T> table; }; template <class T> class GlobalFactory { public: static T* New(const std::string &id) { return factory.New(id); }; static void Register(const std::string &id, AllocBase<T> *allocator) { factory.Register(id, allocator); }; protected: static Factory<T> factory; }; template<class T> Factory<T> GlobalFactory<T>::factory; } // namespace RAT #endif