Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Factories.h

Go 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