Factory.h

Go to the documentation of this file.
00001 /* -*- mode: c++ -*- */
00002 
00014 #ifndef _Factory_H_
00015 #define _Factory_H_
00016 
00017 #include "FactoryException.h"
00018 
00019 #ifdef _MSC_VER
00020 #include "msdevstudio/MSconfig.h"
00021 #endif
00022 
00023 #include <map>
00024 #include <vector>
00025 
00026 namespace hippodraw {
00027 
00043 template < class Type > class Factory
00044 {
00045 private:
00046 
00048   Factory ( const Factory< Type > & );
00049 
00050 protected:
00051 
00053   std::map < std::string, Type * > m_types;
00054 
00058   mutable std::vector< std::string > m_names;
00059 
00062   Factory ( );
00063 
00066   virtual ~Factory();
00067 
00068  public:
00069 
00071   void add ( Type * );
00072 
00075   void remove ( const std::string & name );
00076 
00080   bool exists ( const std::string & name ) const;
00081 
00085   Type * prototype ( const std::string & name ) const;
00086 
00091   Type * create ( const std::string & name );
00092 
00094   const std::vector< std::string > & names () const;
00095 
00096 };
00097 
00098 template < class Type >
00099 Factory < Type >::Factory ( )
00100 {
00101 }
00102 
00103 template< class Type >
00104 Factory<Type>::~Factory ()
00105 {
00106   typename std::map < std::string, Type * > ::iterator first
00107           = m_types.begin();
00108   for ( ; first != m_types.end(); ++first ) {
00109     delete first->second;
00110   }
00111 
00112   m_types.clear ();
00113 }
00114 
00115 template< class Type >
00116 void Factory<Type>::add ( Type * obj )
00117 {
00118   const std::string & name = obj->name ();
00119   m_types[name] = obj;
00120 }
00121 
00122 template < class Type >
00123 void
00124 Factory < Type >::
00125 remove ( const std::string & name )
00126 {
00127   typename std::map < std::string, Type * > ::iterator it
00128     = m_types.find ( name );
00129   if ( it != m_types.end () ) {
00130     m_types.erase ( it );
00131   }
00132 }
00133 
00134 template < class Type >
00135 bool Factory < Type>::
00136 exists ( const std::string & name ) const
00137 {
00138   // Don't use map::operator[]() to find the name, as it will create
00139   // one if it doesn't exist.
00140   typename std::map< std::string, Type * >::const_iterator it 
00141     = m_types.find ( name );
00142 
00143   return it != m_types.end ();
00144 }
00145 
00146 
00147 template< class Type >
00148 Type * Factory<Type>::prototype ( const std::string & name ) const
00149 {
00150   // Don't use map::operator[]() to find the name, as it will create
00151   // one if it doesn't exist.
00152   typename std::map< std::string, Type * >::const_iterator it 
00153     = m_types.find ( name );
00154   if ( it == m_types.end () ) throw FactoryException ( name );
00155 
00156   return it->second;
00157 }
00158 
00159 template< class Type >
00160 Type * Factory<Type>::create ( const std::string & name )
00161 {
00162   Type * obj = prototype ( name );
00163   if ( obj == 0 ) {
00164     return 0;
00165   }
00166   return obj->clone ();
00167 }
00168 
00169 template< class Type >
00170 const std::vector< std::string > & Factory<Type>::names () const
00171 {
00172   m_names.clear ();
00173   typename std::map <std::string, Type *>::const_iterator it 
00174     = m_types.begin ();
00175   for ( ; it != m_types.end (); ++it ) {
00176     m_names.push_back ( it->first );
00177   }
00178 
00179   return m_names;
00180 }
00181 
00182 } // namespace hippodraw
00183 
00184 #endif // _Factory_H_

Generated for HippoDraw Class Library by doxygen