Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Factory.h

Go to the documentation of this file.
00001 #ifndef ANP_FACTORY_H
00002 #define ANP_FACTORY_H
00003 
00015 
00016 // C++
00017 #include <iostream>
00018 #include <map> 
00019 #include <string>
00020 #include <vector>
00021 
00022 // Local
00023 #include "PhysicsNtuple/Handle.h"
00024 
00025 namespace Anp
00026 {
00027    template<class T>
00028    class Factory
00029    {       
00030    public:
00031       
00032       // typedef for functor that creates object of class T
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       // must use Instance() method to access/create Factory
00060       Factory();
00061       ~Factory();
00062 
00063       // Factory is singleton and can not be copied
00064       // These two methods are private and not defined by design
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    // handle unknown algorithm request
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    // handle unknown algorithm request
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    // Atempt to erase handle with key "name"
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 

Generated on Mon Feb 15 11:06:40 2010 for loon by  doxygen 1.3.9.1