CreateFunctor.H

00001 /*! A CreateFunctor is a Functor which creates an object with optional
00002     parameters. The parameter manipulation and object creation are
00003     dissacociated, so that at the point of object creation parameter
00004     type and value need not be known. 
00005 */
00006 //////////////////////////////////////////////////////////////////////////
00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00008 // University of Southern California (USC) and the iLab at USC.         //
00009 // See http://iLab.usc.edu for information about this project.          //
00010 //////////////////////////////////////////////////////////////////////////
00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00013 // in Visual Environments, and Applications'' by Christof Koch and      //
00014 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00015 // pending; application number 09/912,225 filed July 23, 2001; see      //
00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00017 //////////////////////////////////////////////////////////////////////////
00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00019 //                                                                      //
00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00021 // redistribute it and/or modify it under the terms of the GNU General  //
00022 // Public License as published by the Free Software Foundation; either  //
00023 // version 2 of the License, or (at your option) any later version.     //
00024 //                                                                      //
00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00028 // PURPOSE.  See the GNU General Public License for more details.       //
00029 //                                                                      //
00030 // You should have received a copy of the GNU General Public License    //
00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00033 // Boston, MA 02111-1307 USA.                                           //
00034 //////////////////////////////////////////////////////////////////////////
00035 //
00036 // Primary maintainer for this file: David J. Berg <dberg@usc.edu>
00037 // $HeadURL:svn://ilab.usc.edu/trunk/saliency/src/GenericUtils/CreateFunctor.H$
00038 
00039 #ifndef UTIL_CREATEFUNCTOR_H_DEFINED
00040 #define UTIL_CREATEFUNCTOR_H_DEFINED
00041 
00042 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work
00043 
00044 #include "GenericUtils/ParamList.H"
00045 #include "GenericUtils/ObjCreator.H"
00046 #include "Util/log.H"
00047 
00048 #include <typeinfo>
00049 
00050 //######################################################################
00051 //CreateListHolder
00052 //
00053 // This is an abstract class to represent interface to various
00054 // CreateListHolderImpl's which will hold ParamList's for object
00055 // creation. See CreatListHolderImpl for the implementation and 
00056 // CreateFunctor which uses a CreateListHolder. MutPlist must be 
00057 // a ParamList<typename...> Users should not use this class directly. 
00058 //######################################################################
00059 template <class ReturnType, class MutPlist>
00060 class CreateListHolder
00061 {
00062 public:  
00063   //destructor
00064   virtual ~CreateListHolder() { };
00065   
00066   //create a ReturnType
00067   virtual ReturnType* create() const = 0;
00068   
00069   //polymorphicly clone the object
00070   virtual CreateListHolder* clone() const 
00071   {
00072     CreateListHolder* d = doClone();
00073     if ( typeid(*d) != typeid(*this) )
00074       LFATAL("DoClone incorrectly overridden" );
00075     return d;
00076   };
00077 
00078   //update the mutable paramters
00079   template <typename... Params>
00080   void setMutParams(const Params&... params)
00081   {
00082     itsMutParams = ParamList<Params...>(params...);
00083   }
00084   
00085   //update the mutable params in the paramlist 
00086   virtual bool update() = 0;
00087 
00088 protected:
00089   //constructors and assignment
00090   CreateListHolder() : itsMutParams() { };
00091   CreateListHolder(const MutPlist& mutplist) : itsMutParams(mutplist) { };
00092   CreateListHolder(const CreateListHolder& rhs) : itsMutParams(rhs.itsMutParams) { };
00093   CreateListHolder& operator=(const CreateListHolder& rhs) 
00094   { if (this != &rhs) itsMutParams = rhs.itsMutParams; return *this; };
00095 
00096   MutPlist itsMutParams;//our mutable parameter list
00097   
00098 private:
00099   virtual CreateListHolder* doClone() const = 0;
00100 };
00101 
00102 //######################################################################
00103 // CreateListHolderImpl 
00104 // 
00105 // The polymorphic implementation of CreateListHolder. This class
00106 // stores parameter information used in CreateFunctor. Different
00107 // template instantiations will create different derived types all
00108 // accesable through the CreateListHolder interface. MutPlist must be 
00109 // a ParamList<typename...> Users should not use this class directly.
00110 // ######################################################################
00111 template <class ReturnType, class CreateType, class MutPlist, typename... Params> class CreateListHolderImpl;
00112 
00113 //specialization for when there are no parameters
00114 //###################################################################### 
00115 template <class ReturnType, class CreateType, class MutPlist>
00116 class CreateListHolderImpl<ReturnType,CreateType,MutPlist> : public CreateListHolder<ReturnType, MutPlist>
00117 {
00118 public:
00119   //constructor
00120   CreateListHolderImpl() : CreateListHolder<ReturnType, MutPlist>() { };
00121   
00122   //default copy constructor and assignment OK
00123   
00124   //desctructor
00125   virtual ~CreateListHolderImpl() { };
00126   
00127   //create an object of type ReturnType
00128   ReturnType* create() const 
00129   { return new CreateType(); }
00130 
00131   //update the mutable params in the paramlist, return true if an update could be made
00132   virtual bool update()
00133   {
00134     return false;
00135   }
00136 
00137 private:
00138   //actually do the work of clone()
00139   CreateListHolderImpl<ReturnType, CreateType, MutPlist>* doClone() const
00140   {
00141     return new CreateListHolderImpl<ReturnType, CreateType, MutPlist>(*this);
00142   };
00143 };
00144 
00145 //specialization for when there are N parameters
00146 //###################################################################### 
00147 template <class ReturnType, class CreateType, class MutPlist, typename... Params>
00148 class CreateListHolderImpl : public CreateListHolder<ReturnType, MutPlist>
00149 {
00150 public:
00151   //constructor
00152   CreateListHolderImpl(const ParamList<Params...>& paramlist) 
00153     : CreateListHolder<ReturnType, MutPlist>(), itsList(paramlist) { };
00154   
00155   //constructor
00156   CreateListHolderImpl(const Params&... params)
00157     : CreateListHolder<ReturnType, MutPlist>(), itsList(params...) { };
00158   
00159   //default copy constructor and assignment OK
00160   
00161   //desctructor
00162   virtual ~CreateListHolderImpl() { };
00163   
00164   //create an object of type ReturnType
00165   ReturnType* create() const 
00166   { return ObjCreator<CreateType>::create(itsList); }
00167 
00168   //update the mutable params in the paramlist, return true if an update could be made
00169   virtual bool update()
00170   {
00171     return itsList.assign(CreateListHolder<ReturnType, MutPlist>::itsMutParams);
00172   }
00173 
00174 private:
00175   //actually do the work of clone()
00176   CreateListHolderImpl<ReturnType, CreateType, MutPlist, Params...>* doClone() const
00177   {
00178     return new CreateListHolderImpl<ReturnType, CreateType, MutPlist, Params...>(*this);
00179   };
00180   
00181   ParamList<Params...> itsList;//hold our ParamList
00182 };
00183 
00184 //###################################################################### 
00185 // CreateFunctor is a functor that creates an object with optional parameters. The parameter manipulation and object
00186 // creation are dissacociated, so that at the point of object creation parameter type and value need not be known.
00187 // Parameters can be set at functor creation and modified later if desired. A call to operator() will return the desired
00188 // type. The is particularly useful with GenericFactory.H 'ReturnType' is the type of object to return (could be an
00189 // abstract class). The second template must be a ParamList whose types are the types of the mutable parameters, which
00190 // could be a subset of the parameters used to create the object. The result is some fixed and some mutable parameters.
00191 // See UpdateParams() for more details.
00192 //
00193 // Usage: 
00194 //
00195 //Imagine we have a class Circle which can take one or two arguments and
00196 //derives from Shape. operator() prints "I'm a Cicle". Circle has two
00197 //public members p1, and p2 to hold the arguments.
00198 
00199 //  //test functor components
00200 //  ParamList<float,int> pl(1.00f, 1);
00201 //  CreateFunctor<Circle> func(pl);
00202 //  Circle* c = func();
00203 //  LINFO("%3.2f, %d", c->p1, c->p2);
00204 
00205 //  //create Functor from parameters
00206 //  CreateFunctor<Circle> func1(2.00f, 2);
00207 //  CreateFunctor<Circle> func2(10.10f);
00208 //  c = func1();
00209 //  LINFO("%3.2f, %d", c->p1, c->p2);
00210 //  c = func2();
00211 //  LINFO("%3.2f, %d", c->p1, c->p2);
00212 
00213 //  //now, create a derived type of the return type
00214 //  auto func3 = CreateFunctor<Shape>::make<Circle>(pl);
00215 //  Shape* s = func3();
00216 //  (*s)(); //print the message
00217 //  c = dynamic_cast<Circle*>(s);//cast to a circle
00218 //  LINFO("%3.2f, %d", c->p1, c->p2);
00219 
00220 //  //make from some params instead
00221 //  auto func4 = CreateFunctor<Shape>::make<Circle>(33.33f, 55);
00222 //  s = func4();
00223 //  (*s)(); //print the message
00224 //  c = dynamic_cast<Circle*>(s);
00225 //  LINFO("%3.2f, %d", c->p1, c->p2);
00226 //
00227 //  //update both parameter. see updateParams() for more details
00228 //  CreateFunctor<Circle,ParamList<float,int> > func5(2.00f, 2);
00229 //  func5.updateParams(0.0f,0);
00230 //  c = func5();
00231 //  LINFO("%3.2f, %d", c->p1, c->p2);
00232 //  
00233 //  //only the second paramter is able to be changed
00234 //  CreateFunctor<Circle,ParamList<int> > func6(2);
00235 //  func6.updateParams(0);
00236 //  c = func6();
00237 //  LINFO("%3.2f, %d", c->p1, c->p2);
00238 // ######################################################################
00239 template <class ReturnType, class MutPlist = ParamList<>>
00240 class CreateFunctor
00241 {
00242 public:
00243   //empty creation function- particularly when we want to create a derived type and return a base class pointer.
00244   template<class CreateType>
00245   static CreateFunctor<ReturnType, MutPlist> make()
00246   {
00247     CreateListHolderImpl<ReturnType, CreateType, MutPlist> temp;
00248     return CreateFunctor<ReturnType, MutPlist>(temp);
00249   };
00250 
00251   //static creation function which takes a paramlist
00252   template<class CreateType, typename... Params>
00253   static CreateFunctor<ReturnType, MutPlist> make(const ParamList<Params...>& paramlist)
00254   {
00255     CreateListHolderImpl<ReturnType, CreateType, MutPlist, Params...> temp(paramlist);
00256     return CreateFunctor<ReturnType, MutPlist>(temp);
00257   };
00258   
00259   //static creation function which takes params
00260   template<class CreateType, typename... Params>
00261   static CreateFunctor<ReturnType, MutPlist> make(const Params&... params)
00262   {
00263     CreateListHolderImpl<ReturnType, CreateType, MutPlist, Params...> temp(params...);
00264     return CreateFunctor<ReturnType, MutPlist>(temp);
00265   };
00266 
00267   //constructor
00268   CreateFunctor() 
00269     : itsPLH(new CreateListHolderImpl<ReturnType, ReturnType, MutPlist>()) 
00270   { };
00271   
00272   //construct from a param list 
00273   template<typename... Params>
00274   CreateFunctor(const ParamList<Params...>& paramlist) 
00275     : itsPLH(new CreateListHolderImpl<ReturnType, ReturnType, MutPlist, Params...>(paramlist)) 
00276   { };
00277   
00278   //construct from parameters
00279   template<typename... Params>
00280   CreateFunctor(const Params&... params) 
00281     : itsPLH(new CreateListHolderImpl<ReturnType, ReturnType, MutPlist, Params...>(params...)) 
00282   { };
00283   
00284   //copy constructor
00285   CreateFunctor(const CreateFunctor<ReturnType, MutPlist>& rhs) 
00286     : itsPLH( (rhs.itsPLH) ? rhs.itsPLH->clone() : NULL ) { };
00287   
00288   //destructor
00289   ~CreateFunctor() {delete itsPLH; };
00290   
00291   //assignment operator
00292   CreateFunctor<ReturnType, MutPlist>& operator=(const CreateFunctor<ReturnType, MutPlist>& rhs)
00293   {
00294     if (this != &rhs)
00295       {
00296         if (itsPLH) delete itsPLH;
00297         itsPLH = (rhs.itsPLH) ? rhs.itsPLH->clone() : NULL;
00298       }
00299   };
00300   
00301   //function call operator
00302   ReturnType* operator()() const { return (itsPLH) ? itsPLH->create() : NULL; };
00303   
00304   //update our mutable parameters and return true if an update could be made. This relies on the 'assign' function of
00305   //the ParamList used as the second template type. So, only a subset of paramters can be assigned (ie Params does not
00306   //have to be all the possible parameters the object being created could take). See ParamList.H.
00307   template <typename... Params>
00308   bool updateParams(const Params&... params)
00309   {
00310     itsPLH->setMutParams(params...);
00311     return itsPLH->update();
00312   }
00313 
00314 private:
00315   //construct from a CreateListHolderImpl
00316   template<class CreateType, typename... Params>
00317   CreateFunctor(const CreateListHolderImpl<ReturnType, CreateType, MutPlist, Params...>& clhi) : itsPLH(clhi.clone()) 
00318   { };
00319     
00320   //pointer to a CreateListHolderImpl
00321   CreateListHolder<ReturnType, MutPlist>* itsPLH;
00322 };
00323 
00324 #endif //INVT_USE_CPPOX
00325 #endif//UTIL_CREATEFUNCTOR_H_DEFINED
Generated on Sun May 8 08:04:47 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3