//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2006 by Guillaume Chatelet // // Code covered by the MIT License // // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The authors make no representations about the suitability of this software // for any purpose. It is provided "as is" without express or implied warranty. // // This code DOES NOT accompany the book: // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // //////////////////////////////////////////////////////////////////////////////// #ifndef SPCACHEDFACTORY_H_ #define SPCACHEDFACTORY_H_ #include #include #include namespace Loki { //////////////////////////////////////////////////////////////////////////////// /// \class FunctionStorage /// /// \ingroup SmartPointerStorageGroup /// Implementation of the StoragePolicy used by SmartPtr //////////////////////////////////////////////////////////////////////////////// template class FunctionStorage { public: typedef T* StoredType; // the type of the pointee_ object typedef T* InitPointerType; /// type used to declare OwnershipPolicy type. typedef T* PointerType; // type returned by operator-> typedef T& ReferenceType; // type returned by operator* typedef Functor< void , Seq< void* > > FunctorType; // type of the Functor to set FunctionStorage() : pointee_(Default()), functor_() {} // The storage policy doesn't initialize the stored pointer // which will be initialized by the OwnershipPolicy's Clone fn FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_) {} template FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_) {} FunctionStorage(const StoredType& p) : pointee_(p), functor_() {} PointerType operator->() const { return pointee_; } ReferenceType operator*() const { return *pointee_; } void Swap(FunctionStorage& rhs) { std::swap(pointee_, rhs.pointee_); std::swap(functor_, rhs.functor_); } void SetCallBackFunction(const FunctorType &functor) { functor_ = functor; } // Accessors template friend typename FunctionStorage::PointerType GetImpl(const FunctionStorage& sp); template friend const typename FunctionStorage::StoredType& GetImplRef(const FunctionStorage& sp); template friend typename FunctionStorage::StoredType& GetImplRef(FunctionStorage& sp); protected: // Destroys the data stored // (Destruction might be taken over by the OwnershipPolicy) void Destroy() { functor_(this); } // Default value to initialize the pointer static StoredType Default() { return 0; } private: // Data StoredType pointee_; FunctorType functor_; }; template inline typename FunctionStorage::PointerType GetImpl(const FunctionStorage& sp) { return sp.pointee_; } template inline const typename FunctionStorage::StoredType& GetImplRef(const FunctionStorage& sp) { return sp.pointee_; } template inline typename FunctionStorage::StoredType& GetImplRef(FunctionStorage& sp) { return sp.pointee_; } /** * \class SmartPointer * \ingroup EncapsulationPolicyCachedFactoryGroup * \brief Encapsulate the object in a SmartPtr with FunctionStorage policy * * Encapsulate the object in a SmartPtr with FunctionStorage policy. * The object will come back to the Cache as soon as the smartPtr leaves the scope. */ template < class AbstractProduct, template class OwnershipPolicy = RefCounted, class ConversionPolicy = DisallowConversion, template class CheckingPolicy = AssertCheck, template class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS > class SmartPointer { private: typedef SmartPtr< AbstractProduct,OwnershipPolicy, ConversionPolicy, CheckingPolicy, FunctionStorage, ConstnessPolicy > CallBackSP; protected: typedef CallBackSP ProductReturn; SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {} virtual ~SmartPointer(){}; ProductReturn encapsulate(AbstractProduct* pProduct) { CallBackSP SP(pProduct); SP.SetCallBackFunction(fun); return SP; } AbstractProduct* release(ProductReturn &pProduct) { return GetImpl(pProduct); } const char* name(){return "smart pointer";} private: void smartPointerCallbackFunction(void* pSP) { CallBackSP &SP(*reinterpret_cast(pSP)); ReleaseObject(SP); } virtual void ReleaseObject(ProductReturn &object)=0; const typename CallBackSP::FunctorType fun; }; } // namespace Loki #endif /*SPCACHEDFACTORY_H_*/