Factory.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00020 #ifndef COIL_FACTORY_H
00021 #define COIL_FACTORY_H
00022 
00023 #include <string>
00024 #include <map>
00025 #include <algorithm>
00026 #include <vector>
00027 #include <coil/Singleton.h>
00028 
00029 // for Windows DLL export
00030 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
00031 #   ifdef LIBRARY_EXPORTS
00032 #      define EXTERN
00033 #      define DLL_PLUGIN __declspec(dllexport)
00034 #   else
00035 #      define EXTERN extern
00036 #      define DLL_PLUGIN __declspec(dllimport)
00037 #   endif
00038 #else 
00039 #   define DLL_PLUGIN
00040 #   define EXTERN
00041 #endif /* Windows */
00042 
00043 
00044 namespace coil
00045 {
00057   template <class AbstractClass, class ConcreteClass>
00058   AbstractClass* Creator()
00059   {
00060     return new ConcreteClass();
00061   }
00062 
00074   template <class AbstractClass, class ConcreteClass>
00075   void Destructor(AbstractClass*& obj)
00076   {
00077     if (obj == 0) { return; }
00078     ConcreteClass* tmp = dynamic_cast<ConcreteClass*>(obj);
00079     if (tmp == 0) { return; }
00080     delete obj;
00081     obj = 0;
00082   }
00083 
00097   template <
00098     class AbstractClass,
00099     typename Identifier = std::string,
00100     typename Compare = std::less<Identifier>,
00101     typename Creator = AbstractClass* (*)(),
00102     typename Destructor = void (*)(AbstractClass*&)
00103     >
00104   class Factory
00105   {
00106     class FactoryEntry;
00107   public:
00108 
00109     typedef std::map<Identifier, FactoryEntry> FactoryMap;
00110     typedef typename FactoryMap::iterator     FactoryMapIt;
00111     
00112     enum ReturnCode
00113       {
00114         FACTORY_OK,
00115         FACTORY_ERROR,
00116         ALREADY_EXISTS,
00117         NOT_FOUND,
00118         INVALID_ARG,
00119         UNKNOWN_ERROR
00120       };
00121 
00145     bool hasFactory(const Identifier& id)
00146     {
00147       if (m_creators.count(id) == 0) { return false; }
00148       return true;
00149     }
00150 
00170     std::vector<Identifier> getIdentifiers()
00171     {
00172       std::vector<Identifier> idlist;
00173       idlist.reserve(m_creators.size());
00174 
00175       FactoryMapIt it(m_creators.begin());
00176       FactoryMapIt it_end(m_creators.end());
00177 
00178       while (it != it_end)
00179         {
00180           idlist.push_back(it->first);
00181           ++it;
00182         }
00183       return idlist;
00184     }
00185 
00217     ReturnCode addFactory(const Identifier& id,
00218                           Creator creator,
00219                           Destructor destructor)
00220     {
00221       if (creator == 0 || destructor == 0) { return INVALID_ARG; }
00222       if (m_creators.count(id) != 0) { return ALREADY_EXISTS; }
00223       FactoryEntry f(creator, destructor);
00224       m_creators[id] = f;
00225       return FACTORY_OK;
00226     }
00227 
00253     ReturnCode removeFactory(const Identifier& id)
00254     {
00255       if (m_creators.count(id) == 0) { return NOT_FOUND; }
00256 
00257       m_creators.erase(id);
00258       return FACTORY_OK;
00259     }
00260 
00284     AbstractClass* createObject(const Identifier& id)
00285     {
00286       if (m_creators.count(id) == 0) { return 0; }
00287       return m_creators[id].creator_();
00288     }
00289 
00311     void deleteObject(const Identifier& id, AbstractClass*& obj)
00312     {
00313       if (m_creators.count(id) == 0) { return; }
00314       m_creators[id].destructor_(obj);
00315     }
00316 
00336     void deleteObject(AbstractClass*& obj)
00337     {
00338       FactoryMapIt it(m_creators.begin());
00339       FactoryMapIt it_end(m_creators.end());
00340 
00341       while (it != it_end)
00342         {
00343           it->second.destructor_(obj);
00344           ++it;
00345         }
00346     }
00347 
00348   private:
00349 
00363     class FactoryEntry
00364     {
00365     public:
00366       explicit FactoryEntry()
00367       {
00368       }
00369 
00391       FactoryEntry(Creator creator, Destructor destructor)
00392         : creator_(creator), destructor_(destructor)
00393       {
00394       }
00395       Creator creator_;
00396       Destructor destructor_;
00397     };
00398     FactoryMap m_creators;
00399   };
00400 
00401 
00402 
00416   template <
00417     class AbstractClass,
00418     typename Identifier = std::string,
00419     typename Compare = std::less<Identifier>,
00420     typename Creator = AbstractClass* (*)(),
00421     typename Destructor = void (*)(AbstractClass*&)
00422     >
00423   class GlobalFactory
00424     : public Factory<AbstractClass, Identifier, Compare, Creator, Destructor>,
00425       public coil::Singleton<GlobalFactory<AbstractClass,
00426                                            Identifier,
00427                                            Compare,
00428                                            Creator,
00429                                            Destructor> >
00430   {
00431   public:
00432 
00433   private:
00449     GlobalFactory(){}
00450 
00466     ~GlobalFactory(){}
00467 
00468     friend class Singleton<GlobalFactory>;
00469   };
00470 
00471 }; // namespace coil
00472 #endif // COIL_FACTORY_H


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:37