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 {}; 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 00028 //! Untyped base class for factories which don't require any arguments to construct their product, see Factories.h file notes (see Factory0Arg) 00029 /*! Note that this does not mean the product has to be constructed without arguments... see Factory0Arg1Static for example. */ 00030 struct Factory0ArgBase { 00031 //! functor interface for constructing the product 00032 virtual void* construct()=0; 00033 //! explicit destructor to avoid warnings regarding virtual functions without virtual destructor 00034 virtual ~Factory0ArgBase() {} 00035 }; 00036 //! Typed base class for factories which don't require any arguments to construct their product, see Factories.h file notes 00037 /*! Note that this does not mean the product has to be constructed without arguments... see Factory0Arg1Static for example. */ 00038 template<class Base> 00039 struct Factory0Arg : public Factory0ArgBase { 00040 //! functor interface for constructing the product 00041 virtual Base* operator()()=0; 00042 virtual void* construct() { return operator()(); } 00043 //! concrete class for constructing products of a specified subtype of Base 00044 template<class T> struct Factory : public Factory0Arg { 00045 virtual Base* operator()() { return new T; } //!< functor for constructing the product 00046 }; 00047 }; 00048 //! This class produces objects based on a constant specified as a template parameter 00049 /*! You could also implement this by adding a member field to the factory and passing that to 00050 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00051 * See Factory0Arg1Member */ 00052 template<class Base, class S1, S1 s1> 00053 struct Factory0Arg1Static : public Factory0Arg<Base> { 00054 //! concrete class for constructing products of a specified subtype of Base 00055 template<class T> struct Factory : public Factory0Arg1Static { 00056 virtual Base* operator()() { return new T(s1); } //!< functor for constructing the product 00057 }; 00058 }; 00059 //! This class produces objects based on a constant specified as a factory member 00060 /*! You could also implement this by using a non-type template parameter argument, see Factory0Arg1Static. */ 00061 template<class Base, class M1> 00062 struct Factory0Arg1Member : public Factory0Arg<Base> { 00063 //! concrete class for constructing products of a specified subtype of Base 00064 template<class T> struct Factory : public Factory0Arg1Member { 00065 Factory() : m1() {} //!< use default constructor for #m1 00066 explicit Factory(const M1& im1) : m1(im1) {} //!< use specified value to initalize #m1 00067 M1 m1; //!< storage for the product's constructor value 00068 virtual Base* operator()() { return new T(m1); } //!< functor for constructing the product 00069 }; 00070 }; 00071 //! This class produces objects based on constant values specified as a template parameters 00072 /*! You could also implement this by adding member fields to the factory and passing that to 00073 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00074 * See Factory0Arg1Member for an example how this is done. */ 00075 template<class Base, class S1, S1 s1, class S2, S2 s2> 00076 struct Factory0Arg2Static : public Factory0Arg<Base> { 00077 //! concrete class for constructing products of a specified subtype of Base 00078 template<class T> struct Factory : public Factory0Arg2Static { 00079 virtual Base* operator()() { return new T(s1,s2); } //!< functor for constructing the product 00080 }; 00081 }; 00082 00083 00084 00085 //! 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) 00086 /*! Note that this does not mean the product can only be constructed with only one argument... see Factory1Arg1Static for example. */ 00087 template<class A1> 00088 struct Factory1ArgBase { 00089 //! functor interface for constructing the product 00090 virtual void* construct(const A1& a1)=0; 00091 //! explicit destructor to avoid warnings regarding virtual functions without virtual destructor 00092 virtual ~Factory1ArgBase() {} 00093 }; 00094 //! Typed base class for factories which require a single argument to construct their product, which is passed to the concrete Factory's functor 00095 /*! Note that this does not mean the product can only be constructed with only one argument... see Factory1Arg1Static for example. */ 00096 template<class Base, class A1> 00097 struct Factory1Arg : public Factory1ArgBase<A1> { 00098 //! functor interface for constructing the product 00099 virtual Base* operator()(const A1& a1)=0; 00100 virtual void* construct(const A1& a1) { return operator()(a1); } 00101 //! concrete class for constructing products of a specified subtype of Base 00102 template<class T> struct Factory : public Factory1Arg { 00103 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< functor for constructing the product 00104 }; 00105 }; 00106 //! This class produces objects based on a functor argument and a constant specified as a template parameter 00107 /*! You could also implement this by adding a member field to the factory and passing that to 00108 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00109 * See Factory0Arg1Member for an example how this is done. */ 00110 template<class Base, class A1, class S1, S1 s1> 00111 struct Factory1Arg1Static : public Factory1Arg<Base,A1> { 00112 //! concrete class for constructing products of a specified subtype of Base 00113 template<class T> struct Factory : public Factory1Arg1Static { 00114 virtual Base* operator()(const A1& a1) { return new T(a1,s1); } //!< functor for constructing the product 00115 }; 00116 }; 00117 //! This class produces objects based on a constant specified as a template parameter and a constructor argument 00118 /*! You could also implement this by adding a member field to the factory and passing that to 00119 * the target constuctor instead of the non-type template parameter (which has some restrictions). 00120 * See Factory0Arg1Member for an example how this is done. */ 00121 template<class Base, class S1, S1 s1, class A1> 00122 struct Factory1Static1Arg : public Factory1Arg<Base,A1> { 00123 //! concrete class for constructing products of a specified subtype of Base 00124 template<class T> struct Factory : public Factory1Static1Arg { 00125 virtual Base* operator()(const A1& a1) { return new T(s1,a1); } //!< functor for constructing the product 00126 }; 00127 }; 00128 00129 00130 00131 //! Base class for factories which can create products more than one way, in this case via default constructor (0 arguments) or 1-argument constructor 00132 /*! We use multiple inheritance to combine the Factory0Arg and Factory1Arg base classes. Keep in mind however, 00133 * that all product subtypes must support all constr*/ 00134 template<class Base, class A1> 00135 struct Factory0_1Arg : public virtual Factory0Arg<Base>, public virtual Factory1Arg<Base,A1> { 00136 using Factory0Arg<Base>::operator(); 00137 using Factory1Arg<Base,A1>::operator(); 00138 //! concrete class for constructing products of a specified subtype of Base 00139 template<class T> struct Factory : public Factory0_1Arg { 00140 virtual Base* operator()() { return new T; } //!< 0 argument functor for constructing the product 00141 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< 1 argument functor for constructing the product 00142 }; 00143 }; 00144 //! 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... 00145 /*! Thus, we only ever call the product's 1 argument constructor, but provide more options in the factory interface... */ 00146 template<class Base, class S1, S1 s1, class A1> 00147 struct Factory1Static_1Arg : public Factory0_1Arg<Base,A1> { 00148 //! concrete class for constructing products of a specified subtype of Base 00149 template<class T> struct Factory : public Factory1Static_1Arg { 00150 virtual Base* operator()() { return new T(s1); } //!< 0 argument functor for constructing the product using the static value 00151 virtual Base* operator()(const A1& a1) { return new T(a1); } //!< 1 argument functor for constructing the product 00152 }; 00153 }; 00154 00155 /*! @file 00156 * @brief Defines a variety of factory templates which can be used with FamilyFactory. 00157 * This is not (and couldn't be) an exhaustive list of Factory configurations. It provides some commonly used 00158 * configurations, and should give you some examples and ideas how to create your own for more complex cases. 00159 * 00160 * Factory0Arg and Factory1Arg allow you to instantiate classes with 0 or 1 arguments respectively. Subclasses of 00161 * these interfaces allow you to specify additional parameters to the product's constructor call. Factory0_1Arg 00162 * shows how to combine Factory configurations so you can have multiple constructor options at runtime. 00163 * 00164 * @author ejt (Creator) 00165 * 00166 * $Author: ejt $ 00167 * $Name: tekkotsu-4_0 $ 00168 * $Revision: 1.2 $ 00169 * $State: Exp $ 00170 * $Date: 2007/11/09 18:08:29 $ 00171 */ 00172 00173 #endif |
Tekkotsu v4.0 |
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4 |