00001 #ifndef ANP_FACTORY_H
00002 #define ANP_FACTORY_H
00003
00015
00016
00017 #include <iostream>
00018 #include <map>
00019 #include <string>
00020 #include <vector>
00021
00022
00023 #include "PhysicsNtuple/Handle.h"
00024
00025 namespace Anp
00026 {
00027 template<class T>
00028 class Factory
00029 {
00030 public:
00031
00032
00033 typedef Handle<T> (*Creator)();
00034
00035 public:
00036
00037 static Factory& Instance();
00038
00039 bool Register(const std::string &name, Creator creator);
00040
00041 bool Unregister(const std::string &name);
00042
00043 Handle<T> Create(const std::string &name);
00044
00045 const std::vector<std::string> List() const;
00046
00047 bool Hold(const std::string &name, Handle<T> ptr);
00048
00049 Handle<T> Get(const std::string &name) const;
00050
00051 bool Remove(const std::string &name);
00052
00053 void Clear();
00054
00055 void Print() const;
00056
00057 private:
00058
00059
00060 Factory();
00061 ~Factory();
00062
00063
00064
00065 Factory(const Factory &);
00066 const Factory& operator =(const Factory &);
00067
00068 private:
00069
00070 static Factory *fgInstance;
00071
00072 typedef std::map<std::string, Creator> CallMap;
00073 typedef std::map<std::string, Handle<T> > HoldMap;
00074
00075 CallMap fCalls;
00076 HoldMap fHolds;
00077 };
00078
00082 template<class T> Factory<T>* Factory<T>::fgInstance = 0;
00083 }
00084
00085 #ifndef __CINT__
00086
00104
00105 #define REGISTER_ANP_OBJECT(BASE,CLASS) \
00106 namespace \
00107 { \
00108 Anp::Handle<Anp::BASE> Create##BASE() \
00109 { \
00110 return Anp::Handle<Anp::BASE>(new Anp::CLASS); \
00111 } \
00112 bool Registered##BASE = Anp::Factory<Anp::BASE>::Instance(). \
00113 Register(#CLASS, Create##BASE); \
00114 }
00115
00116 #define REGISTER_ANY_OBJECT(PREF,BASE,CLASS) \
00117 namespace \
00118 { \
00119 Anp::Handle<PREF::BASE> Create##PREF##BASE() \
00120 { \
00121 return Anp::Handle<PREF::BASE>(new PREF::CLASS); \
00122 } \
00123 bool Registered##BASE = Anp::Factory<PREF::BASE>::Instance(). \
00124 Register(#CLASS, Create##PREF##BASE); \
00125 }
00126
00130
00131 template<class T>
00132 Anp::Factory<T>::Factory()
00133 {
00134 }
00135
00136 template<class T>
00137 Anp::Factory<T>::~Factory()
00138 {
00139 }
00140
00141 template<class T>
00142 Anp::Factory<T>& Anp::Factory<T>::Instance()
00143 {
00144 if(!fgInstance)
00145 {
00146 fgInstance = new Anp::Factory<T>();
00147 }
00148
00149 return *fgInstance;
00150 }
00151
00152 template<class T>
00153 bool Anp::Factory<T>::Register(const std::string &name, Creator creator)
00154 {
00155 if(!fCalls.insert(typename CallMap::value_type(name, creator)).second)
00156 {
00157 std::cerr << "Factory<T>::Register - " << name << " already exists" << std::endl;
00158 return false;
00159 }
00160
00161 return true;
00162 }
00163
00164 template<class T>
00165 bool Anp::Factory<T>::Unregister(const std::string &name)
00166 {
00167 return fCalls.erase(name) == 1;
00168 }
00169
00170 template<class T>
00171 Anp::Handle<T> Anp::Factory<T>::Create(const std::string &name)
00172 {
00173 typename CallMap::const_iterator it = fCalls.find(name);
00174
00175
00176 if(it == fCalls.end())
00177 {
00178 std::cerr << "Factory<T>::Create - don't know anything about " << name << std::endl;
00179 return Handle<T>(NULL);
00180 }
00181
00182 return (it->second)();
00183 }
00184
00185 template<class T>
00186 const std::vector<std::string> Anp::Factory<T>::List() const
00187 {
00188 std::vector<std::string> svec;
00189
00190 typename CallMap::const_iterator it = fCalls.begin();
00191 for(; it != fCalls.end(); ++it)
00192 {
00193 svec.push_back(it -> first);
00194 }
00195
00196 return svec;
00197 }
00198
00199 template<class T>
00200 bool Anp::Factory<T>::Hold(const std::string &name, Handle<T> ptr)
00201 {
00202 return fHolds.insert(typename HoldMap::value_type(name, ptr)).second;
00203 }
00204
00205 template<class T>
00206 Anp::Handle<T> Anp::Factory<T>::Get(const std::string &name) const
00207 {
00208 typename HoldMap::const_iterator it = fHolds.find(name);
00209
00210
00211 if(it == fHolds.end())
00212 {
00213 std::cerr << "Factory<T>::Get - don't know anything about " << name << std::endl;
00214 return Handle<T>(NULL);
00215 }
00216
00217 return it->second;
00218 }
00219
00220 template<class T>
00221 bool Anp::Factory<T>::Remove(const std::string &name)
00222 {
00223
00224
00225
00226 if(fHolds.erase(name) < 1)
00227 {
00228 std::cerr << "Factory<T>::Remove - don't know anything about " << name << std::endl;
00229 return false;
00230 }
00231
00232 return true;
00233 }
00234
00235 template<class T>
00236 void Anp::Factory<T>::Clear()
00237 {
00238 fHolds.clear();
00239 }
00240
00241 template<class T>
00242 void Anp::Factory<T>::Print() const
00243 {
00244 std::cout << "Print: Factory<> knows about " << fCalls.size() << " objects" << std::endl;
00245
00246 typename CallMap::const_iterator it = fCalls.begin();
00247 for(; it != fCalls.end(); ++it)
00248 {
00249 std::cout << "Registerted object name " << it -> first << std::endl;
00250 }
00251 }
00252
00253 #endif
00254 #endif
00255
00256