SPCachedFactory.h

00001 
00002 // The Loki Library
00003 // Copyright (c) 2006 by Guillaume Chatelet
00004 //
00005 // Code covered by the MIT License
00006 //
00007 // Permission to use, copy, modify, distribute and sell this software for any 
00008 // purpose is hereby granted without fee, provided that the above copyright 
00009 // notice appear in all copies and that both that copyright notice and this 
00010 // permission notice appear in supporting documentation.
00011 //
00012 // The authors make no representations about the suitability of this software
00013 // for any purpose. It is provided "as is" without express or implied warranty.
00014 //
00015 // This code DOES NOT accompany the book:
00016 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
00017 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
00018 //
00020 
00021 // $Id: SPCachedFactory.h 810 2007-02-25 14:36:28Z syntheticpp $
00022 
00023 #ifndef SPCACHEDFACTORY_H_
00024 #define SPCACHEDFACTORY_H_
00025 
00038 #include <loki/Functor.h>
00039 #include <loki/SmartPtr.h>
00040 #include <loki/CachedFactory.h>
00041 
00042 namespace Loki
00043 {
00044 
00060 
00061     template <class T>
00062     class FunctionStorage
00063     {
00064     public:
00066         typedef T* StoredType;
00068         typedef T* InitPointerType;
00070         typedef T* PointerType;
00072         typedef T& ReferenceType;
00074         typedef Functor< void , Seq< void* > > FunctorType;
00075 
00076         FunctionStorage() : pointee_(Default()), functor_()
00077         {}
00078 
00079         // The storage policy doesn't initialize the stored pointer 
00080         //     which will be initialized by the OwnershipPolicy's Clone fn
00081         FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_)
00082         {}
00083 
00084         template <class U>
00085         FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_)
00086         {}
00087         
00088         FunctionStorage(const StoredType& p) : pointee_(p), functor_() {}
00089         
00090         PointerType operator->() const { return pointee_; }
00091         
00092         ReferenceType operator*() const { return *pointee_; }
00093         
00094         void Swap(FunctionStorage& rhs)
00095         { 
00096           std::swap(pointee_, rhs.pointee_);
00097           std::swap(functor_, rhs.functor_);
00098         }
00099         
00102         void SetCallBackFunction(const FunctorType &functor)
00103         {
00104           functor_ = functor;
00105         }
00106     
00107         // Accessors
00108         template <class F>
00109         friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp);
00110 
00111         template <class F>
00112         friend const typename FunctionStorage<F>::StoredType& GetImplRef(const FunctionStorage<F>& sp);
00113 
00114         template <class F>
00115         friend typename FunctionStorage<F>::StoredType& GetImplRef(FunctionStorage<F>& sp);
00116 
00117     protected:
00118         // Destroys the data stored
00119         // (Destruction might be taken over by the OwnershipPolicy)
00120         void Destroy()
00121         {
00122             functor_(this);
00123         }
00124 
00125         // Default value to initialize the pointer
00126         static StoredType Default()
00127         { return 0; }
00128     
00129     private:
00130         // Data
00131         StoredType pointee_;
00132         FunctorType functor_;
00133     };
00134 
00135     template <class T>
00136     inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp)
00137     { return sp.pointee_; }
00138 
00139     template <class T>
00140     inline const typename FunctionStorage<T>::StoredType& GetImplRef(const FunctionStorage<T>& sp)
00141     { return sp.pointee_; }
00142 
00143     template <class T>
00144     inline typename FunctionStorage<T>::StoredType& GetImplRef(FunctionStorage<T>& sp)
00145     { return sp.pointee_; }
00146 
00157      template
00158      <
00159           class AbstractProduct,
00160           template <class> class OwnershipPolicy = RefCounted,
00161         class ConversionPolicy = DisallowConversion,
00162         template <class> class CheckingPolicy = AssertCheck,
00163         template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS 
00164      >     
00165      class SmartPointer
00166      {
00167      private:
00168              typedef SmartPtr< AbstractProduct,OwnershipPolicy,
00169                ConversionPolicy, CheckingPolicy,
00170                FunctionStorage, ConstnessPolicy > CallBackSP;
00171      protected:           
00172            typedef CallBackSP ProductReturn;
00173            SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {}
00174            virtual ~SmartPointer(){};
00175            
00176            ProductReturn encapsulate(AbstractProduct* pProduct)
00177            {
00178                     CallBackSP SP(pProduct);
00179                     SP.SetCallBackFunction(fun);
00180                 return SP;
00181            }
00182            
00183            AbstractProduct* release(ProductReturn &pProduct)
00184            {
00185                 return GetImpl(pProduct);
00186            }
00187            
00188            const char* name(){return "smart pointer";}
00189 
00190      private:
00191            SmartPointer& operator=(const SmartPointer&);
00192            SmartPointer(const SmartPointer&);
00193              void smartPointerCallbackFunction(void* pSP)
00194              {
00195                     CallBackSP &SP(*reinterpret_cast<CallBackSP*>(pSP));
00196                     ReleaseObject(SP);
00197              }
00198            virtual void ReleaseObject(ProductReturn &object)=0;
00199            const typename CallBackSP::FunctorType fun;
00200      };
00201 
00202 } // namespace Loki
00203 
00204 #endif /*SPCACHEDFACTORY_H_*/

Generated on Sun Feb 25 16:52:28 2007 for Loki by  doxygen 1.5.1-p1