Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
Factories.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_Factories_h_ 00003 #define INCLUDED_Factories_h_ 00004 00005 //! A factory interface which doesn't actually allow anything to be produced (for completeness, like 'NULL') 00006 template<typename=void> 00007 struct FactoryInvalidT { 00008 //! concrete class for not doing anything 00009 template<class U> struct Factory : public FactoryInvalidT<U> {}; 00010 }; 00011 //! specialization: all invalid factories are the same... 00012 typedef FactoryInvalidT<> FactoryInvalid; 00013 00014 // Alternate implementation of FactoryInvalid just for reference: 00015 // (I prefer the one used above though, because it provides a (unused) template for the base class like the other factory types) 00016 #if 0 00017 //! A factory interface which doesn't actually allow anything to be produced (for completeness, like 'NULL') 00018 struct FactoryInvalid { 00019 //! concrete class for not doing anything (prototype here, "implementation" follows) 00020 template<class U> struct Factory; 00021 }; 00022 //! implementation of concrete class for not doing anything 00023 template<class U> struct FactoryInvalid::Factory : public FactoryInvalid {}; 00024 #endif 00025 00026 00027 //! Untyped base class for factories which don't require any arguments to construct their product, see Factories.h file notes (see Factory0Arg) 00028 /*! Note that this does not mean the product has to be constructed without arguments... see Factory0Arg1Static for example. */ 00029 struct Factory0ArgBase { 00030 //! functor interface for constructing the product 00031 virtual void* construct()=0; 00032 //! explicit destructor to avoid warnings regarding virtual functions without virtual destructor 00033 virtual ~Factory0ArgBase() {} 00034 }; 00035 //! Typed base class for factories which don't require any arguments to construct their product, see Factories.h file notes 00036 /*! Note that this does not mean the product has to be constructed without arguments... see Factory0Arg1Static for example. */ 00037 template<class Base> 00038 struct Factory0Arg : public Factory0ArgBase { 00039 //! functor interface for constructing the product 00040 virtual Base* operator()()=0; 00041 virtual void* construct() { return operator()(); } 00042 //! concrete class for constructing products of a specified subtype of Base 00043 template<class T> struct Factory : public Factory0Arg<Base> { 00044 virtual Base* operator()() { return new T; } //!< functor for constructing the product 00045 }; 00046 }; 00047 //! This class produces objects based on a constant specified as a template parameter 00048 /*! You could also implement this by adding a member field to the factory and passing that to 00049 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00050 * See Factory0Arg1Member */ 00051 template<class Base, class S1, S1 s1> 00052 struct Factory0Arg1Static : public Factory0Arg<Base> { 00053 //! concrete class for constructing products of a specified subtype of Base 00054 template<class T> struct Factory : public Factory0Arg1Static<Base,S1,s1> { 00055 virtual Base* operator()() { return new T(s1); } //!< functor for constructing the product 00056 }; 00057 }; 00058 //! This class produces objects based on a constant specified as a factory member 00059 /*! You could also implement this by using a non-type template parameter argument, see Factory0Arg1Static. */ 00060 template<class Base, class M1> 00061 struct Factory0Arg1Member : public Factory0Arg<Base> { 00062 //! concrete class for constructing products of a specified subtype of Base 00063 template<class T> struct Factory : public Factory0Arg1Member<Base,M1> { 00064 Factory() : m1() {} //!< use default constructor for #m1 00065 explicit Factory(const M1& im1) : m1(im1) {} //!< use specified value to initalize #m1 00066 M1 m1; //!< storage for the product's constructor value 00067 virtual Base* operator()() { return new T(m1); } //!< functor for constructing the product 00068 }; 00069 }; 00070 //! This class produces objects based on constant values specified as a template parameters 00071 /*! You could also implement this by adding member fields to the factory and passing that to 00072 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00073 * See Factory0Arg1Member for an example how this is done. */ 00074 template<class Base, class S1, S1 s1, class S2, S2 s2> 00075 struct Factory0Arg2Static : public Factory0Arg<Base> { 00076 //! concrete class for constructing products of a specified subtype of Base 00077 template<class T> struct Factory : public Factory0Arg2Static<Base,S1,s1,S2,s2> { 00078 virtual Base* operator()() { return new T(s1,s2); } //!< functor for constructing the product 00079 }; 00080 }; 00081 //! A factory for singleton classes which return the instance via getInstance() 00082 template<class T> 00083 class SingletonFactory : public Factory0Arg<T> { 00084 public: 00085 //! returns the singleton instance, factory-style 00086 virtual T* operator()() { return &T::getInstance(); } 00087 }; 00088 00089 00090 00091 //! Untyped base class for factories which require a single argument to construct their product, which is passed to the concrete Factory's functor (see Factory1Arg) 00092 /*! Note that this does not mean the product can only be constructed with only one argument... see Factory1Arg1Static for example. */ 00093 template<class A1> 00094 struct Factory1ArgBase { 00095 //! functor interface for constructing the product 00096 virtual void* construct(const A1& a1)=0; 00097 //! explicit destructor to avoid warnings regarding virtual functions without virtual destructor 00098 virtual ~Factory1ArgBase() {} 00099 }; 00100 //! Typed base class for factories which require a single argument to construct their product, which is passed to the concrete Factory's functor 00101 /*! Note that this does not mean the product can only be constructed with only one argument... see Factory1Arg1Static for example. */ 00102 template<class Base, class A1> 00103 struct Factory1Arg : public Factory1ArgBase<A1> { 00104 //! functor interface for constructing the product 00105 virtual Base* operator()(const A1& a1)=0; 00106 virtual void* construct(const A1& a1) { return operator()(a1); } 00107 //! concrete class for constructing products of a specified subtype of Base 00108 template<class T> struct Factory : public Factory1Arg<Base,A1> { 00109 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< functor for constructing the product 00110 }; 00111 }; 00112 //! This class produces objects based on a functor argument and a constant specified as a template parameter 00113 /*! You could also implement this by adding a member field to the factory and passing that to 00114 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00115 * See Factory0Arg1Member for an example how this is done. */ 00116 template<class Base, class A1, class S1, S1 s1> 00117 struct Factory1Arg1Static : public Factory1Arg<Base,A1> { 00118 //! concrete class for constructing products of a specified subtype of Base 00119 template<class T> struct Factory : public Factory1Arg1Static<Base,A1,S1,s1> { 00120 virtual Base* operator()(const A1& a1) { return new T(a1,s1); } //!< functor for constructing the product 00121 }; 00122 }; 00123 //! This class produces objects based on a constant specified as a template parameter and a constructor argument 00124 /*! You could also implement this by adding a member field to the factory and passing that to 00125 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00126 * See Factory0Arg1Member for an example how this is done. */ 00127 template<class Base, class S1, S1 s1, class A1> 00128 struct Factory1Static1Arg : public Factory1Arg<Base,A1> { 00129 //! concrete class for constructing products of a specified subtype of Base 00130 template<class T> struct Factory : public Factory1Static1Arg<Base,S1,s1,A1> { 00131 virtual Base* operator()(const A1& a1) { return new T(s1,a1); } //!< functor for constructing the product 00132 }; 00133 }; 00134 00135 00136 00137 //! Base class for factories which can create products more than one way, in this case via default constructor (0 arguments) or 1-argument constructor 00138 /*! We use multiple inheritance to combine the Factory0Arg and Factory1Arg base classes. Keep in mind however, 00139 * that all product subtypes must support all constr*/ 00140 template<class Base, class A1> 00141 struct Factory0_1Arg : public virtual Factory0Arg<Base>, public virtual Factory1Arg<Base,A1> { 00142 using Factory0Arg<Base>::operator(); 00143 using Factory1Arg<Base,A1>::operator(); 00144 //! concrete class for constructing products of a specified subtype of Base 00145 template<class T> struct Factory : public Factory0_1Arg<Base,A1> { 00146 virtual Base* operator()() { return new T; } //!< 0 argument functor for constructing the product 00147 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< 1 argument functor for constructing the product 00148 }; 00149 }; 00150 //! Variant of Factory0_1Arg, this uses a constant non-type template parameter to specify a default value to use when the 0-argument functor is called... 00151 /*! Thus, we only ever call the product's 1 argument constructor, but provide more options in the factory interface... */ 00152 template<class Base, class S1, S1 s1, class A1> 00153 struct Factory1Static_1Arg : public Factory0_1Arg<Base,A1> { 00154 //! concrete class for constructing products of a specified subtype of Base 00155 template<class T> struct Factory : public Factory1Static_1Arg<Base,S1,s1,A1> { 00156 virtual Base* operator()() { return new T(s1); } //!< 0 argument functor for constructing the product using the static value 00157 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< 1 argument functor for constructing the product 00158 }; 00159 }; 00160 00161 /*! @file 00162 * @brief Defines a variety of factory templates which can be used with FamilyFactory. 00163 * This is not (and couldn't be) an exhaustive list of Factory configurations. It provides some commonly used 00164 * configurations, and should give you some examples and ideas how to create your own for more complex cases. 00165 * 00166 * Factory0Arg and Factory1Arg allow you to instantiate classes with 0 or 1 arguments respectively. Subclasses of 00167 * these interfaces allow you to specify additional parameters to the product's constructor call. Factory0_1Arg 00168 * shows how to combine Factory configurations so you can have multiple constructor options at runtime. 00169 * 00170 * @author ejt (Creator) 00171 */ 00172 00173 #endif |
Tekkotsu v5.1CVS |
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3 |