factory.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _FACTORY_H_
00023 #define _FACTORY_H_
00024
00025 #include <string>
00026 #include <map>
00027
00028 #include <dcl/exception.h>
00029
00030 namespace dbp {
00031
00032 namespace internal {
00033
00034 template <class ParentT, class T>
00035 ParentT* create_instance() {
00036 return new T();
00037 };
00038
00039 }
00040
00042
00045 class factory_exception: public dbp::exception {
00046 public:
00048 factory_exception(const std::string &msg): exception(msg) { }
00049 };
00050
00051 class factory_non_reg_exception: public factory_exception {
00052 public:
00053 factory_non_reg_exception(const std::string &msg):
00054 factory_exception(msg) { }
00055 virtual const char* what() const throw();
00056 };
00057
00058 class factory_already_reg_exception: public factory_exception {
00059 public:
00060 factory_already_reg_exception(const std::string &msg):
00061 factory_exception(msg) { }
00062 virtual const char* what() const throw();
00063 };
00064
00065 class factory_unreg_exception: public factory_exception {
00066 public:
00067 factory_unreg_exception(const std::string &msg):
00068 factory_exception(msg) { }
00069 virtual const char* what() const throw();
00070 };
00071
00073
00077 template <class T>
00078 class factory {
00079 public:
00081
00088 T* create(const std::string &name) {
00089 if (!is_registered(name))
00090 throw factory_non_reg_exception(name);
00091 return _creator[name]();
00092 };
00094
00099 template <class RealT>
00100 void register_class(const std::string &name) {
00101 if (is_registered(name))
00102 throw factory_already_reg_exception(name);
00103 _creator[name] = &internal::create_instance<T, RealT>;
00104 };
00106
00111 void unregister_class(const std::string &name) {
00112 if (!_creator.erase(name))
00113 throw factory_unreg_exception(name);
00114 };
00116
00122 bool is_registered(const std::string &name) {
00123 return _creator.find(name) != _creator.end();
00124 };
00125 private:
00126 typedef T *(*create_instance_func)();
00127 std::map<std::string, create_instance_func> _creator;
00128 };
00129
00130 }
00131
00132 #endif
00133