| [746ff1] | 1 | /*
 | 
|---|
 | 2 |  * Factory.hpp
 | 
|---|
 | 3 |  *
 | 
|---|
 | 4 |  *  Created on: Jan 3, 2011
 | 
|---|
 | 5 |  *      Author: heber
 | 
|---|
 | 6 |  */
 | 
|---|
 | 7 | 
 | 
|---|
 | 8 | #ifndef FACTORY_HPP_
 | 
|---|
 | 9 | #define FACTORY_HPP_
 | 
|---|
 | 10 | 
 | 
|---|
 | 11 | // include config.h
 | 
|---|
 | 12 | #ifdef HAVE_CONFIG_H
 | 
|---|
 | 13 | #include <config.h>
 | 
|---|
 | 14 | #endif
 | 
|---|
 | 15 | 
 | 
|---|
 | 16 | #include <map>
 | 
|---|
| [724564] | 17 | #include <typeinfo>
 | 
|---|
 | 18 | 
 | 
|---|
 | 19 | #include "Assert.hpp"
 | 
|---|
| [746ff1] | 20 | 
 | 
|---|
 | 21 | #include "Creator.hpp"
 | 
|---|
 | 22 | 
 | 
|---|
 | 23 | class FactoryTest;
 | 
|---|
 | 24 | 
 | 
|---|
 | 25 | /**
 | 
|---|
 | 26 |  * This template produces the generic factory pattern.
 | 
|---|
 | 27 |  *
 | 
|---|
 | 28 |  * <h1> Factory Howto </h1>
 | 
|---|
 | 29 |  * <h2> Introduction </h2>
 | 
|---|
 | 30 |  *
 | 
|---|
 | 31 |  * A factory is a class that instantiates other types. In order to be able to
 | 
|---|
 | 32 |  * do so the following prerequisites must be met:
 | 
|---|
 | 33 |  * -# there is a list of types the factory should be able to produce
 | 
|---|
 | 34 |  * -# they all must be derived from a common class (e.g. an interface) which is
 | 
|---|
 | 35 |  *    the type references from the factory will be returned as.
 | 
|---|
 | 36 |  *
 | 
|---|
 | 37 |  * The reason for the last one is that it is not possible -- except by an ugly
 | 
|---|
 | 38 |  * static_cast -- to retrieve the particular type and if nonetheless needed,
 | 
|---|
 | 39 |  * factory is probably the wrong pattern). After all what a factory does is
 | 
|---|
 | 40 |  * hiding the specifics of a certain subtype, e.g. to control a motor it is not
 | 
|---|
 | 41 |  * necessary to know how fast it goes and what it precisely does, you just need
 | 
|---|
 | 42 |  * need the throttle as a control and some kind of rpm feedback. This control
 | 
|---|
 | 43 |  * and feedback would be abstracted into the interface class.
 | 
|---|
 | 44 |  *
 | 
|---|
 | 45 |  * <h2>How to make a class Factory</h2>
 | 
|---|
 | 46 |  *
 | 
|---|
 | 47 |  * If you want to make a class a Factory you can use the following sequence of
 | 
|---|
 | 48 |  * steps.
 | 
|---|
 | 49 |  *
 | 
|---|
 | 50 |  * Before we begin, we assume the following types to represent ...
 | 
|---|
 | 51 |  * - Abstract_Interface_Class: the aforementioned common interface of all
 | 
|---|
 | 52 |  *    particular types the factory should produce.
 | 
|---|
 | 53 |  * - Abstract_Encapsulation_Class: we need to connect the interface class (which
 | 
|---|
 | 54 |  *    must not be a template) with the types to put into the factory. Hence, we
 | 
|---|
 | 55 |  *    need this (templated) class that encapsulates each possible type as its
 | 
|---|
 | 56 |  *    template argument while deriving from (and implementing) the abstract
 | 
|---|
 | 57 |  *    interface as well.
 | 
|---|
 | 58 |  * - MyFactory: Your specific factory that spills out references to
 | 
|---|
 | 59 |  *    Abstract_Interface_Class that are embodied by
 | 
|---|
 | 60 |  *    Abstract_Encapsulation_Class instances.
 | 
|---|
 | 61 |  *
 | 
|---|
 | 62 |  * For present code, have a look at RandomNumberDistributionFactory.def,
 | 
|---|
 | 63 |  * RandomNumberDistribution_Encapsulation.hpp and
 | 
|---|
 | 64 |  * RandomNumberDistributionFactory.hpp.
 | 
|---|
 | 65 |  *
 | 
|---|
 | 66 |  * @attention{
 | 
|---|
 | 67 |  * One last \b warning before we begin: Your types should reside in a distinct
 | 
|---|
 | 68 |  * (and not the global) namespace, otherwise you may get strange errors such
 | 
|---|
 | 69 |  * as
 | 
|---|
 | 70 |  * \verbatim
 | 
|---|
 | 71 |  * /usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error: type/value mismatch at argument 1 in template parameter list for âtemplate<class T> class stubâ
 | 
|---|
 | 72 |  * /usr/include/boost/preprocessor/iteration/detail/local.hpp:34: error:   expected a type, got â(FactoryTypeList::ListOfKnownTypes)0uâ
 | 
|---|
 | 73 |  * \endverbatim
 | 
|---|
 | 74 |  * i.e. he cannot discern between the enumerated types and the true types due.
 | 
|---|
 | 75 |  * @remarks But having your particular types in their own name space is always
 | 
|---|
 | 76 |  *          a good idea.
 | 
|---|
 | 77 |  *          }
 | 
|---|
 | 78 |  *
 | 
|---|
 | 79 |  * Now beginning, first remember that all we need is a list of already present
 | 
|---|
 | 80 |  * types, i.e. implemented classes. The rest is the stuff below which is all
 | 
|---|
 | 81 |  * you need (and although it looks like quite a lot, it is actually not).
 | 
|---|
 | 82 |  *
 | 
|---|
 | 83 |  * Then, do the following steps:
 | 
|---|
 | 84 |  * - create a file "RandomNumberDistributionFactory.def" containing only
 | 
|---|
 | 85 |  *   preprocessor defines as follows:
 | 
|---|
 | 86 |  *   @code
 | 
|---|
 | 87 |  *   #ifndef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
 | 
|---|
 | 88 |  *   #define RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
 | 
|---|
 | 89 |  *
 | 
|---|
 | 90 |  *   #define type_seq (uniform_smallint)(uniform_int)
 | 
|---|
 | 91 |  *   #define Abstract_Interface_Class RandomNumberDistribution
 | 
|---|
 | 92 |  *   #define Abstract_Encapsulation_Class RandomNumberDistribution_Encapsulation
 | 
|---|
 | 93 |  *   #define type_name_space boost::
 | 
|---|
| [1afcbe] | 94 |  *   #undef type_suffix
 | 
|---|
| [746ff1] | 95 |  *
 | 
|---|
 | 96 |  *   #endif //RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
 | 
|---|
 | 97 |  *   @endcode
 | 
|---|
 | 98 |  *   where \a type_seq is the list of types, each element in round brackets,
 | 
|---|
 | 99 |  *   \a Abstract_Interface_Class is the class name of the abstract base class
 | 
|---|
 | 100 |  *   which a reference to the factory spills out, and
 | 
|---|
 | 101 |  *   \a Abstract_Encapsulation_Class is the class name of the (templated)
 | 
|---|
 | 102 |  *   encapsulation class of each type. Optionally, these types may reside in
 | 
|---|
| [1afcbe] | 103 |  *   some other name_space, define this one via \a type_name_space (with suffixes
 | 
|---|
 | 104 |  *   double colons!). If you need something appended to each type, such as "<>"
 | 
|---|
 | 105 |  *   then add in \a type_suffix. Note that the first two and the last line are
 | 
|---|
 | 106 |  *   just to avoid double inclusion, also the define made therein is used for
 | 
|---|
 | 107 |  *   the following step ...
 | 
|---|
| [746ff1] | 108 |  * - create the undefine file "RandomNumberDistributionFactory.undef" which
 | 
|---|
 | 109 |  *   undefines all the previously made definitions to allow for more factories
 | 
|---|
 | 110 |  *   created without the danger of the various defines getting in the way of
 | 
|---|
 | 111 |  *   each other:
 | 
|---|
 | 112 |  *   @code
 | 
|---|
 | 113 |  *   #ifdef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
 | 
|---|
 | 114 |  *
 | 
|---|
 | 115 |  *   #undef type_seq
 | 
|---|
 | 116 |  *   #undef type_seq_size
 | 
|---|
 | 117 |  *   #undef Abstract_Interface_Class
 | 
|---|
 | 118 |  *   #undef Abstract_Encapsulation_Class
 | 
|---|
 | 119 |  *   #undef type_name_space
 | 
|---|
| [1afcbe] | 120 |  *   #undef type_suffix
 | 
|---|
| [746ff1] | 121 |  *
 | 
|---|
 | 122 |  *   #undef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
 | 
|---|
 | 123 |  *   #endif
 | 
|---|
 | 124 |  *   @endcode
 | 
|---|
 | 125 |  * - Create the encapsulation of the desired types, listed in type_seq via a
 | 
|---|
 | 126 |  *   templated class:
 | 
|---|
 | 127 |  *   @code
 | 
|---|
 | 128 |  *    #include "Creator.hpp"  // the creator wrapper
 | 
|---|
 | 129 |  *    #include "RandomNumberDistribution.hpp" // the abstract interface class
 | 
|---|
 | 130 |  *    template <class type>
 | 
|---|
 | 131 |  *    class RandomNumberDistribution_Encapsulation :
 | 
|---|
 | 132 |  *      public RandomNumberDistribution,  // inherit from abstract interface
 | 
|---|
 | 133 |  *      public Creator<   // and creator wrapper that has to know about ...
 | 
|---|
 | 134 |  *        RandomNumberDistribution,  // .. the abstract interface as well ..
 | 
|---|
 | 135 |  *        RandomNumberDistribution_Encapsulation<type>  // .. and the
 | 
|---|
 | 136 |  *                                // encapsulation class we right now define
 | 
|---|
 | 137 |  *        >
 | 
|---|
 | 138 |  *    {
 | 
|---|
 | 139 |  *    public:
 | 
|---|
 | 140 |  *      // ... some interface functions here with template implementation ...
 | 
|---|
 | 141 |  *      // i.e. those defined as virtual functions in the abstract interface
 | 
|---|
 | 142 |  *
 | 
|---|
 | 143 |  *      RandomNumberDistribution_Encapsulation() {} // constructor
 | 
|---|
 | 144 |  *      virtual ~RandomNumberDistribution_Encapsulation() {} // virtual destructor
 | 
|---|
 | 145 |  *    private:
 | 
|---|
 | 146 |  *      type encapsulated_type; // the instance of the type to encapsulate
 | 
|---|
 | 147 |  *    };
 | 
|---|
 | 148 |  *   @endcode
 | 
|---|
 | 149 |  * - in the header of your factory put these before any declaration:
 | 
|---|
 | 150 |  *   @code
 | 
|---|
 | 151 |  *   // has to be appear BEFORE Factory.hpp is included!
 | 
|---|
 | 152 |  *   #include "RandomNumberDistributionFactory.def"
 | 
|---|
 | 153 |  *   #include "CodePatterns/FactoryTypeList.hpp"
 | 
|---|
| [1afcbe] | 154 |  *   #include "RandomNumberDistributionFactory.undef"
 | 
|---|
| [746ff1] | 155 |  *   #include "CodePatterns/Factory.hpp"
 | 
|---|
 | 156 |  *   @endcode
 | 
|---|
 | 157 |  *   Then declare your factory by inheriting from Factory<Abstract_Interface_Class>
 | 
|---|
 | 158 |  *   @code
 | 
|---|
 | 159 |  *   class RandomNumberDistributionFactory :
 | 
|---|
 | 160 |  *     public Factory<RandomNumberDistribution>
 | 
|---|
 | 161 |  *   {
 | 
|---|
 | 162 |  *     RandomNumberDistributionFactory();
 | 
|---|
 | 163 |  *     virtual ~RandomNumberDistributionFactory();
 | 
|---|
 | 164 |  *   };
 | 
|---|
 | 165 |  *   #include "RandomNumberDistributionFactory.undef"
 | 
|---|
 | 166 |  *   @endcode
 | 
|---|
 | 167 |  *   where the last includes undefines the defines made in the first step and
 | 
|---|
 | 168 |  *   assures that another factory can be created without any old defines
 | 
|---|
 | 169 |  *   getting in the way.
 | 
|---|
 | 170 |  *   @note FactoryTypeList.hpp is necessary as we can't have a forward
 | 
|---|
 | 171 |  *         declaration of an enum which we need in the header of Factory<T>.
 | 
|---|
 | 172 |  *         Hence, there is an extra class the wraps the enum which we inherit.
 | 
|---|
 | 173 |  * - finally implement the factory by:
 | 
|---|
 | 174 |  *   @code
 | 
|---|
 | 175 |  *   #include "RandomNumberDistribution_Encapsulation.hpp"
 | 
|---|
 | 176 |  *   #include "RandomNumberDistributionFactory.hpp"
 | 
|---|
 | 177 |  *   // has to be included BEFORE Factory_impl.hpp!
 | 
|---|
 | 178 |  *   #include "RandomNumberDistributionFactory.def"
 | 
|---|
 | 179 |  *   #include "CodePatterns/Factory_impl.hpp"
 | 
|---|
 | 180 |  *
 | 
|---|
 | 181 |  *   RandomNumberDistributionFactory::RandomNumberDistributionFactory() {}
 | 
|---|
 | 182 |  *   RandomNumberDistributionFactory::~RandomNumberDistributionFactory() {}
 | 
|---|
 | 183 |  *
 | 
|---|
 | 184 |  *   CONSTRUCT_SINGLETON(RandomNumberDistributionFactory)
 | 
|---|
 | 185 |  *   CONSTRUCT_FACTORY(RandomNumberDistribution)
 | 
|---|
 | 186 |  *
 | 
|---|
 | 187 |  *   #include "RandomNumberDistributionFactory.undef"
 | 
|---|
 | 188 |  *   @endcode
 | 
|---|
 | 189 |  *
 | 
|---|
 | 190 |  * That's all.
 | 
|---|
 | 191 |  */
 | 
|---|
 | 192 | template <class T>
 | 
|---|
 | 193 | class Factory : public FactoryTypeList<T>
 | 
|---|
 | 194 | {
 | 
|---|
 | 195 | public:
 | 
|---|
 | 196 |   /** Constructor of class Factory.
 | 
|---|
 | 197 |    *
 | 
|---|
 | 198 |    */
 | 
|---|
 | 199 |   Factory()
 | 
|---|
 | 200 |   {
 | 
|---|
 | 201 |     FillEnumTable();
 | 
|---|
 | 202 |     FillPrototypeTable();
 | 
|---|
 | 203 |   }
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 |   /** (virtual) Destructor of class Factory.
 | 
|---|
 | 206 |    *
 | 
|---|
 | 207 |    */
 | 
|---|
 | 208 |   virtual ~Factory()
 | 
|---|
 | 209 |   {
 | 
|---|
 | 210 |     // clear out factories map to allow boost::shared_ptr to do their work (i.e. to release mem)
 | 
|---|
 | 211 |     // this is necessary as factory is an object
 | 
|---|
 | 212 |     enums.clear();
 | 
|---|
 | 213 |     names.clear();
 | 
|---|
 | 214 |     for (typename InstanceTable::iterator iter = PrototypeTable.begin();
 | 
|---|
 | 215 |         !PrototypeTable.empty();
 | 
|---|
 | 216 |         iter = PrototypeTable.begin()) {
 | 
|---|
 | 217 |       delete (iter->second);
 | 
|---|
 | 218 |       PrototypeTable.erase(iter);
 | 
|---|
 | 219 |     }
 | 
|---|
 | 220 |     PrototypeTable.clear();
 | 
|---|
 | 221 |   }
 | 
|---|
 | 222 | 
 | 
|---|
 | 223 | 
 | 
|---|
 | 224 |   /** Enumeration of all types known to this factory
 | 
|---|
 | 225 |    */
 | 
|---|
 | 226 |   typedef enum FactoryTypeList<T>::ListOfKnownTypes TypeList;
 | 
|---|
 | 227 | 
 | 
|---|
 | 228 |   /** Setter for currenttype to produce.
 | 
|---|
 | 229 |    *
 | 
|---|
 | 230 |    * @param instance_name name of type
 | 
|---|
 | 231 |    */
 | 
|---|
 | 232 |   void setCurrentType(const std::string instance_name)
 | 
|---|
 | 233 |   {
 | 
|---|
 | 234 |     ASSERT(enums.count(instance_name) != 0,
 | 
|---|
 | 235 |         "Factory<"+toString(typeid(T).name())+">::setCurrentType() - type "+instance_name+" is not registered.");
 | 
|---|
 | 236 |     currenttype = enums[instance_name];
 | 
|---|
 | 237 |   }
 | 
|---|
 | 238 | 
 | 
|---|
 | 239 |   /** Setter for currenttype to produce.
 | 
|---|
 | 240 |    *
 | 
|---|
 | 241 |    * @param instance_type enumeration index of type
 | 
|---|
 | 242 |    */
 | 
|---|
 | 243 |   void setCurrentType(TypeList instance_type)
 | 
|---|
 | 244 |   {
 | 
|---|
 | 245 |     ASSERT(names.count(instance_type) != 0,
 | 
|---|
 | 246 |         "Factory<"+toString(typeid(T).name())+">::setCurrentType() - enum type "+toString(instance_type)+" is not registered.");
 | 
|---|
 | 247 |     currenttype = instance_type;
 | 
|---|
 | 248 |   }
 | 
|---|
 | 249 | 
 | 
|---|
 | 250 |   /** Getter for currenttype to produce.
 | 
|---|
 | 251 |    *
 | 
|---|
 | 252 |    * @return name of currenttype
 | 
|---|
 | 253 |    */
 | 
|---|
 | 254 |   const std::string & getCurrentTypeName() const
 | 
|---|
 | 255 |   {
 | 
|---|
 | 256 |     return names[currenttype];
 | 
|---|
 | 257 |   }
 | 
|---|
 | 258 | 
 | 
|---|
 | 259 |   /** Getter for currenttype to produce.
 | 
|---|
 | 260 |    *
 | 
|---|
 | 261 |    * @return enumeration index of currenttype
 | 
|---|
 | 262 |    */
 | 
|---|
 | 263 |   TypeList getCurrentTypeEnum() const
 | 
|---|
 | 264 |   {
 | 
|---|
 | 265 |     return currenttype;
 | 
|---|
 | 266 |   }
 | 
|---|
 | 267 | 
 | 
|---|
 | 268 |   /** Getter for desired type of product.
 | 
|---|
 | 269 |    *
 | 
|---|
 | 270 |    * @param enumeration index of product
 | 
|---|
 | 271 |    * @return reference to copy of product
 | 
|---|
 | 272 |    */
 | 
|---|
 | 273 |   T* getProduct(TypeList instance_type) const
 | 
|---|
 | 274 |   {
 | 
|---|
 | 275 |     ASSERT(names.count(instance_type) != 0,
 | 
|---|
 | 276 |         "Factory<"+toString(typeid(T).name())+">::getProduct() - enum type "+toString(instance_type)+" is not registered.");
 | 
|---|
 | 277 |     return PrototypeTable[instance_type]->create();
 | 
|---|
 | 278 |   }
 | 
|---|
 | 279 | 
 | 
|---|
 | 280 |   /** Getter for desired type of product.
 | 
|---|
 | 281 |    *
 | 
|---|
 | 282 |    * @param name of product
 | 
|---|
 | 283 |    * @return reference to copy of product
 | 
|---|
 | 284 |    */
 | 
|---|
 | 285 |   T* getProduct(const std::string instance_name) const
 | 
|---|
 | 286 |   {
 | 
|---|
 | 287 |     ASSERT(enums.count(instance_name) != 0,
 | 
|---|
 | 288 |         "Factory<"+toString(typeid(T).name())+">::getProduct() - type name "+instance_name+" is not registered.");
 | 
|---|
 | 289 |     return PrototypeTable[ enums[instance_name] ]->create();
 | 
|---|
 | 290 |   }
 | 
|---|
 | 291 | 
 | 
|---|
| [724564] | 292 |   /** Getter for desired type of product.
 | 
|---|
 | 293 |    *
 | 
|---|
 | 294 |    * @param type_info object of the desired type
 | 
|---|
 | 295 |    * @return reference to copy of current type product or NULL if type mismatch
 | 
|---|
 | 296 |    */
 | 
|---|
 | 297 |   T* getProduct(const std::type_info &instance_type_info) const
 | 
|---|
 | 298 |   {
 | 
|---|
 | 299 |     ASSERT(types.count(instance_type_info.name()) != 0,
 | 
|---|
 | 300 |         "Factory<"+toString(typeid(T).name())+">::getProduct() - type info name "+instance_type_info.name()+" is not registered.");
 | 
|---|
 | 301 |     return PrototypeTable[ types[instance_type_info.name()] ]->create();
 | 
|---|
 | 302 |   }
 | 
|---|
| [746ff1] | 303 | 
 | 
|---|
 | 304 |   /** Getter for current type of product.
 | 
|---|
 | 305 |    *
 | 
|---|
 | 306 |    * @return reference to copy of current type product
 | 
|---|
 | 307 |    */
 | 
|---|
 | 308 |   T* getProduct() const
 | 
|---|
 | 309 |   {
 | 
|---|
 | 310 |     return PrototypeTable[currenttype]->create();
 | 
|---|
 | 311 |   }
 | 
|---|
 | 312 | 
 | 
|---|
 | 313 |   /** Getter for the name of the desired type of product.
 | 
|---|
 | 314 |    *
 | 
|---|
 | 315 |    * @return name of distribution
 | 
|---|
 | 316 |    */
 | 
|---|
 | 317 |   const std::string &getName(TypeList instance_type) const
 | 
|---|
 | 318 |   {
 | 
|---|
 | 319 |     ASSERT(names.count(instance_type) != 0,
 | 
|---|
 | 320 |         "Factory<"+toString(typeid(T).name())+">::getName() - enum type "+toString(instance_type)+" is not registered.");
 | 
|---|
 | 321 |     return names[instance_type];
 | 
|---|
 | 322 |   }
 | 
|---|
 | 323 | 
 | 
|---|
 | 324 |   /** Getter for the enumeration index of the desired type of product.
 | 
|---|
 | 325 |    *
 | 
|---|
 | 326 |    * @return enum of distribution
 | 
|---|
 | 327 |    */
 | 
|---|
 | 328 |    TypeList getEnum(const std::string instance_name) const
 | 
|---|
 | 329 |    {
 | 
|---|
 | 330 |      ASSERT(enums.count(instance_name) != 0,
 | 
|---|
 | 331 |          "Factory<"+toString(typeid(T).name())+">::getEnum() - type name "+instance_name+" is not registered.");
 | 
|---|
 | 332 |      return enums[instance_name];
 | 
|---|
 | 333 |    }
 | 
|---|
 | 334 | 
 | 
|---|
 | 335 | 
 | 
|---|
 | 336 | protected:
 | 
|---|
 | 337 | 
 | 
|---|
 | 338 |   /** Creates instances of all possible distribution types
 | 
|---|
 | 339 |    *  and stores them in \a DistributionPrototypeTable.
 | 
|---|
 | 340 |    */
 | 
|---|
 | 341 |   void FillPrototypeTable();
 | 
|---|
 | 342 | 
 | 
|---|
 | 343 |   /** Create association for enums to strings and vice versa
 | 
|---|
 | 344 |    *  and stores them in \a distributions tables.
 | 
|---|
 | 345 |    */
 | 
|---|
 | 346 |   void FillEnumTable();
 | 
|---|
 | 347 | 
 | 
|---|
| [724564] | 348 |   typedef std::map<
 | 
|---|
 | 349 |       std::string,
 | 
|---|
 | 350 |       TypeList
 | 
|---|
 | 351 |       > TypeMap;
 | 
|---|
| [746ff1] | 352 |   typedef std::map<
 | 
|---|
 | 353 |       std::string,
 | 
|---|
 | 354 |       TypeList
 | 
|---|
 | 355 |       > EnumMap;
 | 
|---|
 | 356 |   typedef std::map<
 | 
|---|
 | 357 |       TypeList,
 | 
|---|
 | 358 |       ICreator<T> *
 | 
|---|
 | 359 |       > InstanceTable;
 | 
|---|
 | 360 |   typedef std::map<
 | 
|---|
 | 361 |       TypeList,
 | 
|---|
 | 362 |       std::string
 | 
|---|
 | 363 |       > NameMap;
 | 
|---|
 | 364 | 
 | 
|---|
 | 365 |   static TypeList currenttype;
 | 
|---|
| [724564] | 366 |   static TypeMap types;
 | 
|---|
| [746ff1] | 367 |   static EnumMap enums;
 | 
|---|
 | 368 |   static InstanceTable PrototypeTable;
 | 
|---|
 | 369 |   static NameMap names;
 | 
|---|
 | 370 | };
 | 
|---|
 | 371 | 
 | 
|---|
 | 372 | template <class T> typename Factory<T>::TypeList Factory<T>::currenttype = (typename Factory<T>::TypeList)0;
 | 
|---|
| [724564] | 373 | template <class T> typename Factory<T>::TypeMap Factory<T>::types;
 | 
|---|
| [746ff1] | 374 | template <class T> typename Factory<T>::EnumMap Factory<T>::enums;
 | 
|---|
 | 375 | template <class T> typename Factory<T>::NameMap Factory<T>::names;
 | 
|---|
 | 376 | template <class T> typename Factory<T>::InstanceTable Factory<T>::PrototypeTable;
 | 
|---|
 | 377 | 
 | 
|---|
 | 378 | /**
 | 
|---|
 | 379 |  * This define allows simple instantiation of the necessary factory functions
 | 
|---|
 | 380 |  * at a chosen place.
 | 
|---|
 | 381 |  */
 | 
|---|
 | 382 | #define CONSTRUCT_FACTORY(InstanceType) \
 | 
|---|
 | 383 |     template Factory<InstanceType>::Factory(); \
 | 
|---|
 | 384 |     template Factory<InstanceType>::~Factory(); \
 | 
|---|
 | 385 |     template void Factory<InstanceType>::setCurrentType(const std::string instance_name); \
 | 
|---|
 | 386 |     template void Factory<InstanceType>::setCurrentType(TypeList instance_type); \
 | 
|---|
 | 387 |     template const std::string & Factory<InstanceType>::getCurrentTypeName() const; \
 | 
|---|
 | 388 |     template Factory<InstanceType>::TypeList Factory<InstanceType>::getCurrentTypeEnum() const; \
 | 
|---|
 | 389 |     template InstanceType* Factory<InstanceType>::getProduct(TypeList instance_type) const; \
 | 
|---|
 | 390 |     template InstanceType* Factory<InstanceType>::getProduct(const std::string instance_name) const; \
 | 
|---|
 | 391 |     template const std::string &Factory<InstanceType>::getName(TypeList instance_type) const; \
 | 
|---|
 | 392 |     template Factory<InstanceType>::TypeList Factory<InstanceType>::getEnum(const std::string instance_name) const;
 | 
|---|
 | 393 | 
 | 
|---|
 | 394 | #endif /* FACTORY_HPP_ */
 | 
|---|